<p>I believe it would be easier to answer the question by dividing it into related but more specific questions. Having said that, even if the answers below would be satisfactory, I would still post this on the package's Github repo, the author being informed about this can help other users of this package.</p>
<p>Question 1: Why does <code>runTSNE()</code> work when I use the deprecated <code>use_dimred</code> argument?</p>
<p>Let's create function and call it:</p>
<pre><code>&gt; my_func &lt;- function(dimred) {
+   if(missing(dimred)) {
+     print(&quot;dimred argument is not provided so something else is being done...&quot;)
+   } else {
+     print(dimred)
+   }
+ }
&gt; my_func(42)
[1] 42
&gt; my_func(dimred = 42)
[1] 42
&gt; my_func()
[1] &quot;dimred argument is not provided so something else is being done...&quot;
&gt; my_func(use_dimred = 42)
Error in my_func(use_dimred = 42) : unused argument (use_dimred = 42)
</code></pre>
<p>As expected, we get an error if we call a function with an argument that does not belong to our function: <code>use_dimread</code>. If we define our function with the special argument <code>...</code> however, it works:</p>
<pre><code>&gt; my_func &lt;- function(dimred, ...) {
+   if(missing(dimred)) {
+     print(&quot;dimred argument is not provided so something else is being done...&quot;)
+   } else {
+     print(dimred)
+   }
+ }
&gt; my_func(42)
[1] 42
&gt; my_func(dimred = 42)
[1] 42
&gt; my_func()
[1] &quot;dimred argument is not provided so something else is being done...&quot;
&gt; my_func(use_dimred = 42)
[1] &quot;dimred argument is not provided so something else is being done...&quot;
</code></pre>
<p>Basically when you call a function, the function you are calling can make calls to other functions and the <code>...</code> is basically allowing the user to feed arguments for these let's say &quot;secondary&quot; functions. Apparently <code>R</code> does not care if what you feed as an argument to a function is used or not if the function is defined with the special <code>...</code> argument.</p>
<p>Question 2: Why is <code>runTSNE()</code> working if the supplied <code>use_dimred</code> argument was not used (as shown above)?</p>
<p>If you take a look at the <a href="https://github.com/Alanocallaghan/scater/blob/RELEASE_3_12/R/runTSNE.R" rel="nofollow noreferrer">source code</a>, <code>calculateTSNE()</code>, which <code>runTSNE()</code> runs under the hood, is using PCA if the <code>dimred</code> argument is not provided, its default is NULL anyway. It is been a while since I have used <code>Scater</code> but I think this would mean that the tSNE is being computed on (some number of) PCs.</p>
<p>And as a conclusion, I don't think we can really call this a bug but a rather unexpected behavior because of use of the special <code>...</code> argument in the function definition.</p>

CC BY-SA 4.0
2022-02-01T15:17:44.647Z
well, this is definitely interesting. I did not consider the implications of using the `...`. I will let the developers know for sure.
gbt
CC BY-SA 4.0
2022-02-01T13:23:04.230Z
2022-02-01T13:23:04.230Z
haci
<p>NOTE: I posted the same question on <a href="https://www.biostars.org/p/9507222/" rel="nofollow noreferrer">Biostars</a> but so far no replies there so I figured I would ask here, too.</p>
<p>So, I was running a pipeline which I developed some time ago and a very weird behaviour was found, which had quite an impact over our analyses.</p>
<p>Indeed, the scater's runTSNE() function was subjected to a change in the parameters names and, in particular, the old use_dimred parameter now has a new name, which is dimred.</p>
<p>Interestingly, I was running the pipeline using the runTSNE() function and passing the dimensionality reduction through use_dimred which is apparently deprecated and obtaining very weird results without being aware of that since no warning and/or error was returned.</p>
<p>A quick example:</p>
<pre><code># load some data
library(&quot;scRNAseq&quot;)
library(&quot;scater&quot;)
sce.416b &lt;- LunSpikeInData(which=&quot;416b&quot;)
</code></pre>
<p>check the data and notice no dimensionality reduction is available:</p>
<pre><code>&gt; sce.416b
class: SingleCellExperiment 
dim: 46604 192 
metadata(0):
assays(1): counts
rownames(46604): ENSMUSG00000102693 ENSMUSG00000064842 ...
  ENSMUSG00000095742 CBFB-MYH11-mcherry
rowData names(1): Length
colnames(192): SLX-9555.N701_S502.C89V9ANXX.s_1.r_1
  SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 ...
  SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1
  SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1
colData names(9): Source Name cell line ... spike-in addition block
reducedDimNames(0):            &lt;-- HERE IT IS EMPTY
mainExpName: endogenous
altExpNames(2): ERCC SIRV
</code></pre>
<p>at this point I simply run the runTSNE() function using a non-existent dimred:</p>
<pre><code># set seed
set.seed(001)
# add logcounts
sce.416b &lt;- logNormCounts(sce.416b)
# add random colours to cells
colLabels(sce.416b) &lt;- rep(c(1,2,3,4), 48)
# runTSNE, first try
sce.416b &lt;- runTSNE(sce.416b, use_dimred=&quot;made_up_dimred&quot;, perplexity=30)
# and plot
dev.new(); plotTSNE(sce.416b, colour_by=&quot;label&quot;)
# runTSNE, second try
sce.416b &lt;- runTSNE(sce.416b, use_dimred=&quot;another_made_up_dimred&quot;, perplexity=30)
# and plot
dev.new(); plotTSNE(sce.416b, colour_by=&quot;label&quot;)
# runTSNE, third try
sce.416b &lt;- runTSNE(sce.416b, use_dimred=&quot;a_third_made_up_dimred&quot;, perplexity=30)
# and plot
dev.new(); plotTSNE(sce.416b, colour_by=&quot;label&quot;)
</code></pre>
<p>it, unfortunately, works. Indeed, I now have three TSNE available that I did plot and that are slightly different with each other.</p>
<pre><code>&gt; sce.416b
class: SingleCellExperiment 
dim: 46604 192 
metadata(0):
assays(2): counts logcounts
rownames(46604): ENSMUSG00000102693 ENSMUSG00000064842 ...
  ENSMUSG00000095742 CBFB-MYH11-mcherry
rowData names(1): Length
colnames(192): SLX-9555.N701_S502.C89V9ANXX.s_1.r_1
  SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 ...
  SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1
  SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1
colData names(10): Source Name cell line ... block sizeFactor
reducedDimNames(1): TSNE      &lt;-- THERE YOU GO: A NICE TSNE COMPUTED OVER A NON-EXISTENT DIMRED
mainExpName: endogenous
altExpNames(2): ERCC SIRV
</code></pre>
<p>What is even more interesting is that if I run the function with the newly renamed parameter, i.e. dimred, I do get an error:</p>
<pre><code>&gt; sce.416b &lt;- runTSNE(sce.416b, dimred=&quot;made_up_dimred&quot;, perplexity=30)
Error in value[[3L]](cond) : 
  invalid subscript 'type' in 'reducedDim(&lt;SingleCellExperiment&gt;, type=&quot;character&quot;, ...)':
  'made_up_dimred' not in 'reducedDimNames(&lt;SingleCellExperiment&gt;)'
</code></pre>
<p>But then, if you have an old pipeline which used the runTSNE function with the use_dimred and you're now running an updated version of scater, I have no idea what you may get.</p>
<p>So, as per my question...is this a bug? Has anyone else noticed this weird behaviour? Am I wrong?</p>

<single-cell><tsne>
Is use_dimred deprecated or is this a runTSNE() bug?
# Is use_dimred deprecated or is this a runTSNE() bug?

(Asked by: username_0 on 2022-01-31)

NOTE: I posted the same question on Biostars but so far no replies there so I figured I would ask here, too.
So, I was running a pipeline which I developed some time ago and a very weird behaviour was found, which had quite an impact over our analyses.
Indeed, the scater's runTSNE() function was subjected to a change in the parameters names and, in particular, the old use_dimred parameter now has a new name, which is dimred.
Interestingly, I was running the pipeline using the runTSNE() function and passing the dimensionality reduction through use_dimred which is apparently deprecated and obtaining very weird results without being aware of that since no warning and/or error was returned.
A quick example:
# load some data
library("scRNAseq")
library("scater")
sce.416b <- LunSpikeInData(which="416b")

check the data and notice no dimensionality reduction is available:
> sce.416b
class: SingleCellExperiment 
dim: 46604 192 
metadata(0):
assays(1): counts
rownames(46604): ENSMUSG00000102693 ENSMUSG00000064842 ...
  ENSMUSG00000095742 CBFB-MYH11-mcherry
rowData names(1): Length
colnames(192): SLX-9555.N701_S502.C89V9ANXX.s_1.r_1
  SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 ...
  SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1
  SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1
colData names(9): Source Name cell line ... spike-in addition block
reducedDimNames(0):            <-- HERE IT IS EMPTY
mainExpName: endogenous
altExpNames(2): ERCC SIRV

at this point I simply run the runTSNE() function using a non-existent dimred:
# set seed
set.seed(001)
# add logcounts
sce.416b <- logNormCounts(sce.416b)
# add random colours to cells
colLabels(sce.416b) <- rep(c(1,2,3,4), 48)
# runTSNE, first try
sce.416b <- runTSNE(sce.416b, use_dimred="made_up_dimred", perplexity=30)
# and plot
dev.new(); plotTSNE(sce.416b, colour_by="label")
# runTSNE, second try
sce.416b <- runTSNE(sce.416b, use_dimred="another_made_up_dimred", perplexity=30)
# and plot
dev.new(); plotTSNE(sce.416b, colour_by="label")
# runTSNE, third try
sce.416b <- runTSNE(sce.416b, use_dimred="a_third_made_up_dimred", perplexity=30)
# and plot
dev.new(); plotTSNE(sce.416b, colour_by="label")

it, unfortunately, works. Indeed, I now have three TSNE available that I did plot and that are slightly different with each other.
> sce.416b
class: SingleCellExperiment 
dim: 46604 192 
metadata(0):
assays(2): counts logcounts
rownames(46604): ENSMUSG00000102693 ENSMUSG00000064842 ...
  ENSMUSG00000095742 CBFB-MYH11-mcherry
rowData names(1): Length
colnames(192): SLX-9555.N701_S502.C89V9ANXX.s_1.r_1
  SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 ...
  SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1
  SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1
colData names(10): Source Name cell line ... block sizeFactor
reducedDimNames(1): TSNE      <-- THERE YOU GO: A NICE TSNE COMPUTED OVER A NON-EXISTENT DIMRED
mainExpName: endogenous
altExpNames(2): ERCC SIRV

What is even more interesting is that if I run the function with the newly renamed parameter, i.e. dimred, I do get an error:
> sce.416b <- runTSNE(sce.416b, dimred="made_up_dimred", perplexity=30)
Error in value[[3L]](cond) : 
  invalid subscript 'type' in 'reducedDim(, type="character", ...)':
  'made_up_dimred' not in 'reducedDimNames()'

But then, if you have an old pipeline which used the runTSNE function with the use_dimred and you're now running an updated version of scater, I have no idea what you may get.
So, as per my question...is this a bug? Has anyone else noticed this weird behaviour? Am I wrong?

**Tags:** single-cell, tsne

---

## 1 answers

### Answer by username_1 on 2022-02-01. Score: 1 | Accepted answer

I believe it would be easier to answer the question by dividing it into related but more specific questions. Having said that, even if the answers below would be satisfactory, I would still post this on the package's Github repo, the author being informed about this can help other users of this package.
Question 1: Why does runTSNE() work when I use the deprecated use_dimred argument?
Let's create function and call it:
> my_func <- function(dimred) {
+   if(missing(dimred)) {
+     print("dimred argument is not provided so something else is being done...")
+   } else {
+     print(dimred)
+   }
+ }
> my_func(42)
[1] 42
> my_func(dimred = 42)
[1] 42
> my_func()
[1] "dimred argument is not provided so something else is being done..."
> my_func(use_dimred = 42)
Error in my_func(use_dimred = 42) : unused argument (use_dimred = 42)

As expected, we get an error if we call a function with an argument that does not belong to our function: use_dimread. If we define our function with the special argument ... however, it works:
> my_func <- function(dimred, ...) {
+   if(missing(dimred)) {
+     print("dimred argument is not provided so something else is being done...")
+   } else {
+     print(dimred)
+   }
+ }
> my_func(42)
[1] 42
> my_func(dimred = 42)
[1] 42
> my_func()
[1] "dimred argument is not provided so something else is being done..."
> my_func(use_dimred = 42)
[1] "dimred argument is not provided so something else is being done..."

Basically when you call a function, the function you are calling can make calls to other functions and the ... is basically allowing the user to feed arguments for these let's say "secondary" functions. Apparently R does not care if what you feed as an argument to a function is used or not if the function is defined with the special ... argument.
Question 2: Why is runTSNE() working if the supplied use_dimred argument was not used (as shown above)?
If you take a look at the source code, calculateTSNE(), which runTSNE() runs under the hood, is using PCA if the dimred argument is not provided, its default is NULL anyway. It is been a while since I have used Scater but I think this would mean that the tSNE is being computed on (some number of) PCs.
And as a conclusion, I don't think we can really call this a bug but a rather unexpected behavior because of use of the special ... argument in the function definition.

> **Comments:**
> **username_0**: well, this is definitely interesting. I did not consider the implications of using the `...`. I will let the developers know for sure.  

---

