循环遍历数据帧列表以在 R 中创建数据帧

Loop through a list of dataframes to create dataframes in R

我有以下问题,但我无法找到有效的答案我有多个数据框(准确地说是 35 个),我想向 35 个数据框中的每一个添加另一个包含人口统计数据的数据框。

为简单起见,我有以下示例:

df1 <- data.frame(ID = c(1:3), b = c('x', 'y', 'z'), c = c('gh', 'fg', 'xv'), df = c('z', 'x', 'y'))

df2 <- data.frame(ID = c(1:3), v = c('a', 'mm', 'xc'), hg = c('yty', 'zc', 'cx'), fd = c('z', 'x', 'y'))

df3 <- data.frame(ID = c(1:3, t = c('ae', 'yw', 'zs'), j = c('ewr', 'zd', 'x'), sd = c('z', 'x', 'y'))

df4 <- data.frame(ID = c(1:3), u = c('df', 'y', 'z'), k = c('df', 'zs', 'xf'), f = c('z', 'x', 'y'))
.  
.  
.  
df(n) <- ...  


demo <- data.frame(sex = c('m', 'm', 'f'), age = c('30', '50', '62'), vital_sts = c('a', 'a', 'd'))

我想做的是将 demo 数据帧粘贴到其他每个帧。所以我试过了:

dfList <- list(df1, df2,df3,df4...)  

for (i in 1:length(dfList) {  
     i <- merge(demo,i)  
}

但是,当我检查数据帧时,它们没有合并。 任何帮助将不胜感激。 谢谢!

一个可能的解决方案,之前创建了一个列表,其中包含要与 demo 合并的所有数据帧:

df1 <- data.frame(ID = c(1:3), b = c('x', 'y', 'z'), c = c('gh', 'fg', 'xv'), df = c('z', 'x', 'y'))

df2 <- data.frame(ID = c(1:3), v = c('a', 'mm', 'xc'), hg = c('yty', 'zc', 'cx'), fd = c('z', 'x', 'y'))

demo <- data.frame(sex = c('m', 'm', 'f'), age = c('30', '50', '62'), vital_sts = c('a', 'a', 'd'))

dfs <- list(df1, df2)

l <- lapply(dfs, cbind, demo)
names(l) <-  c("df1", "df2")
list2env(l, .GlobalEnv)

df1

#>   ID b  c df sex age vital_sts
#> 1  1 x gh  z   m  30         a
#> 2  2 y fg  x   m  50         a
#> 3  3 z xv  y   f  62         d

df2

#>   ID  v  hg fd sex age vital_sts
#> 1  1  a yty  z   m  30         a
#> 2  2 mm  zc  x   m  50         a
#> 3  3 xc  cx  y   f  62         d

您还应该给 demo 数据框一个 "ID" 列!这样您就不必希望将人口统计信息正确分配给观察结果,尤其是在脚本在工作过程中仍在更改的情况下。这可以使用 transform 轻松完成(在示例中我只是使用连续 ID 的 1:3)。

res <- lapply(list(df1, df2, df3, df4), merge, transform(demo, ID=1:3))
res
# [[1]]
#   ID b  c df sex age vital_sts
# 1  1 x gh  z   m  30         a
# 2  2 y fg  x   m  50         a
# 3  3 z xv  y   f  62         d
# 
# [[2]]
#   ID  v  hg fd sex age vital_sts
# 1  1  a yty  z   m  30         a
# 2  2 mm  zc  x   m  50         a
# 3  3 xc  cx  y   f  62         d
# 
# [[3]]
#   ID  t   j sd sex age vital_sts
# 1  1 ae ewr  z   m  30         a
# 2  2 yw  zd  x   m  50         a
# 3  3 zs   x  y   f  62         d
# 
# [[4]]
#   ID  u  k f sex age vital_sts
# 1  1 df df z   m  30         a
# 2  2  y zs x   m  50         a
# 3  3  z xf y   f  62         d

如果您的工作区中有数以亿计的数据框,您可以使用 mget(ls(pattern=)) 按模式列出。 (或者更好的是,首先更改您的代码以将它们放入列表中。)

lapply(mget(ls(pat='^df\d+')), merge, transform(demo, ID=1:3))

编辑

如果我理解正确,根据你的评论,你有一个大数据框 DAT,你想从中 assemble 变量组的较小数据框并合并 demo给他们。在这种情况下,我会将这些组的变量名放在命名列表 vgroups 中。接下来,lapply 对其进行同时子集 dat"ID" c 并联 mergedemo.

demo 仍然应该有一个 "ID",因为你不想相信,所有行都按相同的顺序排序,例如 sort(c(3, 10, 1, 100))sort(as.character(c(3, 10, 1, 100))) 或出于任何原因省略的行等

demo <- transform(demo, ID=1:3)  ## identify demo observations

vgroups <- list(g1=c("b", "c", "df"), g2=c("v", "hg", "fd"), g3=c("t", "j", "sd"),
               g4=c("u", "k", "f"))

res1 <- lapply(vgroups, \(x) merge(demo, DAT[, c('ID', x)], by="ID"))  
                          ## saying by ID is even more save --^
res1
# $g1
#   ID sex age vital_sts b  c df
# 1  1   m  30         a x gh  z
# 2  2   m  50         a y fg  x
# 3  3   f  62         d z xv  y
# 
# $g2
#   ID sex age vital_sts  v  hg fd
# 1  1   m  30         a  a yty  z
# 2  2   m  50         a mm  zc  x
# 3  3   f  62         d xc  cx  y
# 
# $g3
#   ID sex age vital_sts  t   j sd
# 1  1   m  30         a ae ewr  z
# 2  2   m  50         a yw  zd  x
# 3  3   f  62         d zs   x  y
# 
# $g4
#   ID sex age vital_sts  u  k f
# 1  1   m  30         a df df z
# 2  2   m  50         a  y zs x
# 3  3   f  62         d  z xf y

访问单个数据帧:

res1$g1
#   ID sex age vital_sts b  c df
# 1  1   m  30         a x gh  z
# 2  2   m  50         a y fg  x
# 3  3   f  62         d z xv  y

如果您仍然想要环境中的单个数据框,请使用 list2env:

list2env(res1)
ls()
# [1] "DAT"     "demo"    "res1"    "vgroups"

数据:

DAT <- structure(list(ID = 1:3, b = c("x", "y", "z"), c = c("gh", "fg", 
"xv"), df = c("z", "x", "y"), f = c("z", "x", "y"), fd = c("z", 
"x", "y"), hg = c("yty", "zc", "cx"), j = c("ewr", "zd", "x"), 
    k = c("df", "zs", "xf"), sd = c("z", "x", "y"), t = c("ae", 
    "yw", "zs"), u = c("df", "y", "z"), v = c("a", "mm", "xc"
    ), x1 = c("gs", "gs", "gs"), x2 = c("cs", "cs", "cs"), x3 = c("tv", 
    "tv", "tv"), x4 = c("fb", "fb", "fb")), row.names = c(NA, 
-3L), class = "data.frame")

demo <- data.frame(sex = c('m', 'm', 'f'), age = c('30', '50', '62'), vital_sts = c('a', 'a', 'd'))