Passing empty index in R
The index argument in subsetting is allowed to be "missing" (see ?"["
):
ff1 = function(x, i) x[i]
ff2 = function(x, i = TRUE) x[i]
ff3 = function(x, i = seq_along(x)) x[i]
ff4 = function(x, i = substitute()) x[i]
a = sample(10)
a
# [1] 3 8 2 6 9 7 5 1 4 10
ff1(a)
# [1] 3 8 2 6 9 7 5 1 4 10
ff2(a)
# [1] 3 8 2 6 9 7 5 1 4 10
ff3(a)
# [1] 3 8 2 6 9 7 5 1 4 10
ff4(a)
# [1] 3 8 2 6 9 7 5 1 4 10
a = runif(1e6)
identical(ff1(a), ff2(a))
#[1] TRUE
identical(ff1(a), ff3(a))
#[1] TRUE
identical(ff1(a), ff4(a))
#[1] TRUE
microbenchmark::microbenchmark(ff1(a), ff2(a), ff3(a), ff4(a), times = 25)
#Unit: milliseconds
# expr min lq median uq max neval
# ff1(a) 2.026772 2.131173 2.207037 2.930885 3.789409 25
# ff2(a) 12.091727 12.151931 12.318625 12.740057 16.829445 25
# ff3(a) 8.930464 9.104118 9.454557 9.643175 13.131213 25
# ff4(a) 2.024684 2.090108 2.156577 2.289166 3.496391 25
Pass empty argument as array index
You can use missing
, so that a missing index implies "select all", which I assume means that the user would just want the grand mean.
myfun <- function(index)
{
if(missing(index)) mean(data) else apply(data[, index, ], 1:2, mean)
}
Indexing a list with an empty index
In short l[]
will return the whole list.
(l <- list(a = 1, b = 2))
l[]
l[] <- list(c=3)
is essentially reassigning what was assigned to each index to now be the result of list(c=3)
. For this example, it is the same as saying l[[1]] <- 3
and l[[2]] <- 3
. From the ?'['
page, which mentions empty indexing a few times:
When an index expression appears on the left side of an assignment (known as subassignment) then that part of x is set to the value of the right hand side of the assignment.
and also
An empty index selects all values: this is most often used to replace all the entries but keep the attributes.
So, I roughly take this to mean each index of l
should evaluate to list(c=3)
.
When you enter (l[] <- list(c = 3))
what is being returned is the replacement value. When you then enter l
or l[]
you will see that the values at each index have been replaced by list(c=3)
.
R drop by empty index on vector inconsistent behaviour
This doesn't work because which(d > 100)
and -which(d > 100)
are the same object: there is no difference between an empty vector and the negative of that empty vector.
For example, imagine you did:
d = 1:10
indexer = which(d > 100)
negative_indexer = -indexer
The two variables would be the same (which is the only consistent behavior- turning all the elements of an empty vector negative leaves it the same since it has no elements).
indexer
#> integer(0)
negative_indexer
#> integer(0)
identical(indexer, negative_indexer)
#> [1] TRUE
At that point, you couldn't expect d[indexer]
and d[negative_indexer]
to give different results. There is also no place to provide an error or warning: it doesn't know when passed an empty vector that you "meant" the negative version of that empty vector.
The solution is that for subsetting there's no reason you need which()
at all: you could use d[d > 10]
instead of your original example. You could therefore use !(d > 100)
or d <= 100
for your negative indexing. This behaves as you'd expect because d > 10
or !(d > 100)
are logical vectors rather than vectors of indices.
Subsetting vector: how to programatically pass negative index safely?
You could use an if()
statement inside the brackets. For example, this will just return the whole vector if n
is zero and remove the sequence 1:n
otherwise.
x <- 1:10
n <- 0
x[ if(n == 0) TRUE else -seq_len(n) ] ## n == 0 is !n for the golfers
# [1] 1 2 3 4 5 6 7 8 9 10
n <- 5
x[ if(n == 0) TRUE else -seq_len(n) ]
# [1] 6 7 8 9 10
Complement of empty index vector is empty index vector
Maybe use;
x <- c(1, 2, 3)
y <- c(4, 5, 6)
y[!y<x]
> y[!y<x]
[1] 4 5 6
x <- c(1, 2, 3)
y <- c(4, 1, 6)
> y[!y<x]
[1] 4 6
>
How to pass nothing as an argument to `[` for subsetting?
After some poking around, alist
seems to do the trick:
x <- matrix(1:6, nrow=3)
x
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
# 1st row
do.call(`[`, alist(x, 1, ))
[1] 1 4
# 2nd column
do.call(`[`, alist(x, , 2))
[1] 4 5 6
From ?alist
:
‘alist’ handles its arguments as if they described function
arguments. So the values are not evaluated, and tagged arguments
with no value are allowed whereas ‘list’ simply ignores them.
‘alist’ is most often used in conjunction with ‘formals’.
A way of dynamically selecting which dimension is extracted. To create the initial
alist
of the desired length, see here (Hadley, using bquote
) or here (using alist
).m <- array(1:24, c(2,3,4))
ndims <- 3
a <- rep(alist(,)[1], ndims)
for(i in seq_len(ndims))
{
slice <- a
slice[[i]] <- 1
print(do.call(`[`, c(list(m), slice)))
}
[,1] [,2] [,3] [,4]
[1,] 1 7 13 19
[2,] 3 9 15 21
[3,] 5 11 17 23
[,1] [,2] [,3] [,4]
[1,] 1 7 13 19
[2,] 2 8 14 20
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
list indexing with [[ vs [ and NULL
Suppose we have a list
as:
mylist = list()
mylist[[1]] = c(1,2,3)
mylist[[2]] = c(4,5,6)
In the concept of list we can say mylist
has two layers which can be accessed by [[
and there element can be accessed by[
like:
mylist[[1]][2]
In your case mylist
has no layer so when you do mylist[1]
R defaultly access first layer and says there are no elements in the first layer of mylist
and returns NULL
but when you do mylist[[1]]
R says Out of Bounds
because the first layer of mylist
has been called and there is no layer at all. That's why R throws error in [[
case.
Related Topics
Function for Polynomials of Arbitrary Order (Symbolic Method Preferred)
Grouping Factor Levels in a Data.Table
Rolling by Group in Data.Table R
Convert from N X M Matrix to Long Matrix in R
How to Create a Binary Vector with 1 If Elements Are Part of the Same Vector
R: Removing Duplicate Elements in a Vector
For Loop Within Custom Function to Create Ggplot Time Series Plots
Separate a Column of a Dataframe in Undefined Number of Columns with R/Tidyverse
R Convert String Date (E.G. "October 1, 2014") to Date Format
Logistic Regression: How to Try Every Combination of Predictors in R
Error When Mapping in Ggmap with API Key (403 Forbidden)
How to Set Ggplot X-Label Equal to Variable Name During Lapply
In Place Modification of Matrices in R
How Can One Mix 2 or More Color Palettes to Show a Combined Color Value