How to subset data frames in a list by row number range with lapply?

Viewed 647

I have a list of data frames. I'd like to extract the first 248 rows of every data frame, then bind them together into one single data frame.

allData is the list of data frames. I've tried to use lapply with subset but I don't know how to refer to row numbers in there. It seems the "subset" argument of the subset function only accept logical vector.

temp <- lapply(allData, subset, subset = (row.names(allData) <= 248))

This code is my idea which does not work, because row.names(allData) actually only applies to the list itself, not the data frames. How to refer to the row numbers of each data frame then?

2 Answers

Using base R, we can do

do.call(rbind, lapply(allData, function(x) x[1:248, ]))

OR with purrr

purrr::map_dfr(allData, ~.[1:248, ])

Using reproducible example with mtcars data and subsetting first 5 rows.

allData <- list(mtcars, mtcars)
do.call(rbind, lapply(allData, function(x) x[1:5, ]))

#                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
#Mazda RX4          21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#Mazda RX4 Wag      21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#Datsun 710         22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#Hornet 4 Drive     21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#Hornet Sportabout  18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
#Mazda RX41         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#Mazda RX4 Wag1     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#Datsun 7101        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#Hornet 4 Drive1    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#Hornet Sportabout1 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2

Another tidyverse approach:

library(tidyverse)

allData %>% 
  map_df(function(x) x %>% slice(1:10))

Since the OP didn't provide sample data, we can use iris dataset:

allData <- list(iris1 = iris[1:50,], # create a list with iris
                iris2 = iris[51:100,], 
                iris3 = iris[101:150,])

allData %>% 
  map_df(~.[1:10,])

## (first 10 rows)
#  Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
#1           5.1         3.5          1.4         0.2     setosa
#2           4.9         3.0          1.4         0.2     setosa
#3           4.7         3.2          1.3         0.2     setosa
#4           4.6         3.1          1.5         0.2     setosa
#5           5.0         3.6          1.4         0.2     setosa
#6           5.4         3.9          1.7         0.4     setosa
#7           4.6         3.4          1.4         0.3     setosa
#8           5.0         3.4          1.5         0.2     setosa
#9           4.4         2.9          1.4         0.2     setosa
#10          4.9         3.1          1.5         0.1     setosa
Related