apply list of indices to list of dataframes

Viewed 55

I need to apply a list of indices to a list of dataframes with a one on one mapping. First element of the list of indices goes to the first dataframe only and so on. List of indices applies to the rows in the dataframes. And a list of complementary dataframes needs to created by selecting rows not mentioned in the indices list.

Here is some sample data:

set.seed(1)
A <- data.frame(matrix(rnorm(40,0,1), nrow = 10))
B <- data.frame(matrix(rnorm(40,2,3), nrow = 10))
C <- data.frame(matrix(rnorm(40,3,4), nrow = 10))

dflis <- list(A,B,C)

# Create a sample row index
ix <- lapply(lapply(dflis,nrow), sample, size = 6)

So far I have managed this working but ugly looking code:

dflis.train <- lapply(seq_along(dflis), function(x) dflis[[x]][ix[[x]],])

dflis.test <- lapply(seq_along(dflis), function(x) dflis[[x]][-ix[[x]],])

Can someone suggest something better, more elegant?

1 Answers

Use Map/mapply instead of the univariate lapply, so that you can iterate over both objects and apply a function, like:

Map(function(d,r) d[r,], dflis, ix)

Or if you want to be fancy:

Map(`[`, dflis, ix, TRUE)

Matches your requested answer.

identical(
  Map(function(d,r) d[r,], dflis, ix),
  lapply(seq_along(dflis), function(x) dflis[[x]][ix[[x]],])
)
#[1] TRUE
Related