在数据框列表中为每个列添加列

时间:2014-09-29 22:09:49

标签: r

这是我在Matching and transposing data between dataframes in R的早期问题的后续行动。我有一个数据框列表,例如:

dfs <- structure(list(df1 = structure(list(id = structure(c(1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "A", class = "factor")), .Names = "id", class = "data.frame", row.names = c(NA, 
-12L)), df2 = structure(list(id = structure(c(1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "B", class = "factor")), .Names = "id", class = "data.frame", row.names = c(NA, 
-12L)), df3 = structure(list(id = structure(c(1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "C", class = "factor")), .Names = "id", class = "data.frame", row.names = c(NA, 
-12L))), .Names = c("df1", "df2", "df3"))

在列表中的每个数据框中,我想根据第四个数据框data的匹配和转置创建一个新列df4

df4 <- structure(list(id = structure(1:3, .Label = c("A", "B", "C"), class = "factor"), 
    x1 = c(9L, 4L, 9L), x2 = c(7L, 2L, 8L), x3 = c(7L, 6L, 7L
    ), x4 = c(9L, 5L, 5L), x5 = c(8L, 8L, 4L), x6 = c(7L, 4L, 
    6L), x7 = c(9L, 8L, 5L), x8 = c(7L, 7L, 8L), x9 = c(5L, 5L, 
    5L), x10 = c(4L, 2L, 8L), x11 = c(9L, 1L, 4L), x12 = c(8L, 
    6L, 5L)), .Names = c("id", "x1", "x2", "x3", "x4", "x5", 
"x6", "x7", "x8", "x9", "x10", "x11", "x12"), class = "data.frame", row.names = c(NA, 
-3L))

我可以使用列表中每个数据帧的单独代码行来实现此目的,例如

dfs$df1$data <- t(df4[unique(match(dfs$df1$id, df4$id)), 2:13])
dfs$df2$data <- t(df4[unique(match(dfs$df2$id, df4$id)), 2:13])
dfs$df3$data <- t(df4[unique(match(dfs$df3$id, df4$id)), 2:13])

但我确信必须有一种更有效,更短的方法来做到这一点。我非常确定我需要使用lapply,但无法弄清楚如何使其发挥作用。例如,我可以使用

lapply(dfs, function(d) t(df4[unique(match(d$id, df4$id)), 2:13]))

将结果作为向量给出,但我无法弄清楚如何在列表的每个数据帧中将这些列作为data的新列插入。有谁知道我怎么能做到这一点?

谢谢!

1 个答案:

答案 0 :(得分:3)

此处尝试使用lapply

lapply(dfs, function(x) {
  cbind(
       x,
       new=unlist(df4[match(x$id[1],df4$id),-1])
       )
})

#$df1
#    id new
#x1   A   9
#x2   A   7
#x3   A   7
#...
#
#$df2
#    id new
#x1   B   4
#x2   B   2
#x3   B   6
#...
# 
#$df3
#    id new
#x1   C   9
#x2   C   8
#x3   C   7
#...