根据向量的内容对列表中的数据帧进行子集化
Subset a dataframes in a list based on the content of a vector
我有一个包含五个数据帧的列表。每个数据框包含一个维度列和 4 个值列。我想根据向量的内容对列表中的每个数据帧进行子集化。
df <- data.frame(x = 1:100, y2 = runif(100, 0, 100), y3 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
df2 <- data.frame(x = 1:100, y2 = runif(100, 0, 100), y3 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
df3 <- data.frame(x = 1:100, y2 = runif(100, 0, 100), y3 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
df4 <- data.frame(x = 1:100, y2= runif(100, 0, 100), y4 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
df5 <- data.frame(x = 1:100, y2= runif(100, 0, 100), y4 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
frames <- list(df, df2, df3, df4, df5)
所以在这个例子中,我的列表是 "frames"。假设我有以下向量:
subs <- 50:60
我的目标是对数据帧列表进行子集化,使每个数据帧只包含第一列的值在 subs 向量内的行。
有什么建议吗?
谢谢,
本
你可以试试lapply
lapply(frames, function(.dat) .dat[with(.dat, x %in% subs),])
如果您的第一列都命名为 x,您可以在框架上使用 lapply:
lapply(frames,function(p){p[p$x %in% subs,]})
在我看来,您几乎所有的问题都与具有相同列的数据框列表有关,这会导致您在每个操作中使用 lapply
循环(这似乎非常低效)。
或者,您可以向量化大部分操作,只需将所有列表绑定到一个对象中,同时维护每个列表的 ID data.frame,当完成所有数据操作后,您可以将它们拆分回使用 split
.
列出
这是一个使用 data.table
s development version on Github 的示例(您可以使用 dplyr::unnest
获得类似的结果)
library(data.table)
Res <- rbindlist(frames, idcol = "ID")[x %between% subs]
# ID x y2 y3 y4 y5
# 1: 1 50 54.692889 58.51886 12.754368 35.61516
# 2: 1 51 21.206308 12.77442 52.440787 93.67734
# 3: 2 50 12.655685 84.55044 3.194644 54.46706
# 4: 2 51 83.840276 61.32614 61.139038 92.39402
# 5: 3 50 54.847797 20.68419 19.585931 48.87072
# 6: 3 51 75.510691 68.17955 98.696579 91.48688
# 7: 4 50 63.203071 95.94132 41.835923 60.68250
# 8: 4 51 75.481676 51.67619 80.393557 24.48381
# 9: 5 50 65.744847 50.36983 86.548843 83.31730
# 10: 5 51 4.956835 57.25666 27.106395 32.92020
最终(在完成所有数据操作之后)您只需要做
split(Res, Res$ID)
为了让 data.frame 回到列表中
我有一个包含五个数据帧的列表。每个数据框包含一个维度列和 4 个值列。我想根据向量的内容对列表中的每个数据帧进行子集化。
df <- data.frame(x = 1:100, y2 = runif(100, 0, 100), y3 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
df2 <- data.frame(x = 1:100, y2 = runif(100, 0, 100), y3 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
df3 <- data.frame(x = 1:100, y2 = runif(100, 0, 100), y3 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
df4 <- data.frame(x = 1:100, y2= runif(100, 0, 100), y4 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
df5 <- data.frame(x = 1:100, y2= runif(100, 0, 100), y4 = runif(100, 0, 100), y4 = runif(100, 0, 100), y5 = runif(100,0,100))
frames <- list(df, df2, df3, df4, df5)
所以在这个例子中,我的列表是 "frames"。假设我有以下向量:
subs <- 50:60
我的目标是对数据帧列表进行子集化,使每个数据帧只包含第一列的值在 subs 向量内的行。
有什么建议吗?
谢谢, 本
你可以试试lapply
lapply(frames, function(.dat) .dat[with(.dat, x %in% subs),])
如果您的第一列都命名为 x,您可以在框架上使用 lapply:
lapply(frames,function(p){p[p$x %in% subs,]})
在我看来,您几乎所有的问题都与具有相同列的数据框列表有关,这会导致您在每个操作中使用 lapply
循环(这似乎非常低效)。
或者,您可以向量化大部分操作,只需将所有列表绑定到一个对象中,同时维护每个列表的 ID data.frame,当完成所有数据操作后,您可以将它们拆分回使用 split
.
这是一个使用 data.table
s development version on Github 的示例(您可以使用 dplyr::unnest
获得类似的结果)
library(data.table)
Res <- rbindlist(frames, idcol = "ID")[x %between% subs]
# ID x y2 y3 y4 y5
# 1: 1 50 54.692889 58.51886 12.754368 35.61516
# 2: 1 51 21.206308 12.77442 52.440787 93.67734
# 3: 2 50 12.655685 84.55044 3.194644 54.46706
# 4: 2 51 83.840276 61.32614 61.139038 92.39402
# 5: 3 50 54.847797 20.68419 19.585931 48.87072
# 6: 3 51 75.510691 68.17955 98.696579 91.48688
# 7: 4 50 63.203071 95.94132 41.835923 60.68250
# 8: 4 51 75.481676 51.67619 80.393557 24.48381
# 9: 5 50 65.744847 50.36983 86.548843 83.31730
# 10: 5 51 4.956835 57.25666 27.106395 32.92020
最终(在完成所有数据操作之后)您只需要做
split(Res, Res$ID)
为了让 data.frame 回到列表中