A list of indices to extract observations from a list of data frames

Viewed 156

I have a list of indices that I want to use to extract observations from a list of data frames. A simplified example is as follows:

#A list of indices used to extract observations based on the time column from the `dat` dataset
time.index <- list(c(1,2,3), c(4,5,6), c(2,3,4))
#A list of data frames in which observations will be extracted based on the time column 
dat <- list(case1=data.frame(time=1:10, y=rnorm(10)), case2=data.frame(time=1:10, y=rnorm(10)), case3=data.frame(time=1:10, y=rnorm(10)))
#The expected result will be like this:
$case1
   time          y
1     1 -0.8954070
2     2  0.0270242
3     3 -0.4256890

$case2
   time       y
4     4  1.5789
5     5 -0.6692
6     6 -2.3306

$case3
   time       y
2     2 -0.7371
3     3 -0.3271
4     4  0.4128

Anyone knows how to achieve that? Much appreciated!

3 Answers

A straightforward way (if you can overlook the ugly bracketing) is the old-school, no-apply loop method.

res <- list()
for(ii in 1:length(time.index)){
  res[[ii]] <- dat[[ii]][dat[[ii]]$time %in% time.index[[ii]] ,]
}

res
[[1]]
  time           y
1    1 -0.05802713
2    2 -0.80779933
3    3 -1.77802107

[[2]]
  time          y
4    4  0.3990907
5    5 -1.5834484
6    6 -0.3626801

[[3]]
  time          y
2    2 -1.8585653
3    3  1.0591013
4    4  0.6903189

You an add the names in the loop or after, like this:

names(res) <- names(dat)

You can use Map :

Map(function(x, y) x[x$time %in% y, ], dat, time.index)

#$case1
#  time     y
#1    1  1.75
#2    2  1.13
#3    3 -1.45

#$case2
#  time     y
#4    4 2.212
#5    5 0.572
#6    6 0.149

#$case3
#  time       y
#2    2 -0.0377
#3    3 -0.1700
#4    4  0.8414

Similarly, using purrr's map2 :

purrr::map2(dat, time.index, ~.x[.x$time %in% .y, ])

In base R, lapply does the job:

setNames(lapply( 1:length(time.index),
   function(x) dat[[x]][dat[[x]]$time %in% time.index[[x]],] ),
   names(dat) )
#$case1
#  time          y
#1    1  1.7458360
#2    2 -0.6945523
#3    3 -0.3699472

#$case2
#  time          y
#4    4  0.5407011
#5    5 -0.3895972
#6    6 -1.1165133

#$case3
#  time          y
#2    2 -0.8736470
#3    3  0.1831833
#4    4  1.0551148
Related