从许多对象的列表中提取数据帧

时间:2018-01-13 08:03:07

标签: r lapply

我在R中有超过1000个对象(z),每个对象包含三个具有不同结构的数据框(df1df2df3)。

  

z1$df1 ... z1000$df1

     

z1$df2 ... z1000$df2

     

z1$df3 ... z1000$df3

我创建了这些对象的列表(list1因此包含z1到z1000)并尝试使用lapply为所有对象提取一种类型的数据帧(df2),然后将它们合并为一个单数据帧。

提取:

对于单个对象,它看起来像这样:

df15<- z15$df2 # I transferred the index of z to the extracted df

我用lapply尝试了一些代码,忽略了索引的传输(我可以为此创建另一个列表)。但是我不知道应该使用什么功能。

List2 <- lapply(list1, function(x))

我尽量避免使用循环,因为它有很多,矢量化速度要快得多。我有这个想法,我从错误的角度看它。

后续合并可以按如下方式进行:

merged <- do.call(rbind, list2)

感谢您的任何建议。

4 个答案:

答案 0 :(得分:1)

听起来您想要将所有df1rbind拉出来,然后对其他数据框执行相同操作。您可以使用purrr::map_dfr从列表的每个元素中提取列并将它们一起绑定。

library('tidyverse')

dummy_df <- list(
  df1 = iris,
  df2 = cars,
  df3 = CO2)

list1 <- list(
  z1 = dummy_df,
  z2 = dummy_df,
  z3 = dummy_df)

df1 <- map_dfr(list1, 'df1')
df2 <- map_dfr(list1, 'df2')
df3 <- map_dfr(list1, 'df3')

如果您想在基数R中执行此操作,则可以使用lapply

df1 <- lapply(list1, function(x) x$df1)
df1_merged <- do.call(rbind, df1)

答案 1 :(得分:0)

一个选项可能是使用lapply提取data.frame,然后使用bind_rows中的dplyr

## The data
df1 <- data.frame(id = c(1:10), name = c(LETTERS[1:10]), stringsAsFactors = FALSE)
df2 <- data.frame(id = 11:20, name = LETTERS[11:20], stringsAsFactors = FALSE)
df3 <- data.frame(id = 21:30, name = LETTERS[15:24], stringsAsFactors = FALSE)
df4 <- data.frame(id = 121:130, name = LETTERS[15:24], stringsAsFactors = FALSE)

z1 <- list(df1 = df1, df2 = df2, df3 = df3)
z2 <- list(df1 = df1, df2 = df2, df3 = df3)
z3 <- list(df1 = df1, df2 = df2, df3 = df3)
z4 <- list(df1 = df1, df2 = df2, df3 = df4) #DFs can contain different data

# z <- list(z1, z2, z3, z4)
# Dynamically populate list z with many list object
z <- as.list(mget(paste("z",1:4,sep="")))


df1_all <- bind_rows(lapply(z, function(x) x$df1))
df2_all <- bind_rows(lapply(z, function(x) x$df2))
df3_all <- bind_rows(lapply(z, function(x) x$df3))


## Result for df3_all
> tail(df3_all)
##    id name
## 35 125    S
## 36 126    T
## 37 127    U
## 38 128    V
## 39 129    W
## 40 130    X

答案 2 :(得分:0)

试试这个:

lapply(list1, "[[", "df2")

或者如果你想rbind他们在一起:

do.call("rbind", lapply(list1, "[[", "df2"))

结果数据框中的行名称将标识每行的来源。

没有使用任何包裹。

注意

我们可以使用此输入来测试上面的代码。 BOD是内置数据框:

z <- list(df1 = BOD, df2 = BOD, df3 = BOD)
list1 <- list(z1 = z, z2 = z)

答案 3 :(得分:0)

这也是data.table::rbindlist,可能比do.call(rbind, lapply(...))dplyr::bind_rows

更快
library(data.table)
rbindlist(lapply(list1, "[[", "df2"))