【发布时间】:2014-10-26 03:18:18
【问题描述】:
我正在尝试根据每个列中的元素连接两个数据框 df 和 myData。 df 中的列故意包含嵌套列表,如果嵌套列表中的元素与 myData 的元素匹配,我想加入。我想在 df 中保留不匹配的行(左连接)。
这是一个示例,首先在 df 中没有嵌套列表。
df = data.frame(a=1:5)
df$x1= c("a", "b", "g", "a", "a")
str(df)
'data.frame': 5 obs. of 2 variables:
$ a : int 1 2 3 4 5
$ x1: chr "a" "b" "g" "a" ...
myData <- data.frame(x1=c("a", "g", "q"), x2= c("za", "zg", "zq"), stringsAsFactors = FALSE)
现在,我们可以加入第 x1 列:
#using a for loop
df$x2 <- NA
for(id in 1:nrow(myData)){
df$x2[df$x1 %in% myData$x1[id]] <- myData$x2[id]
}
或者使用 dplyr:
library(dplyr)
df = data.frame(a=1:5)
df$x1= c("a", "b", "g", "a", "a")
df %>%
left_join(myData)
现在,考虑使用嵌套列表的 df。
l1 = list(letters[1:5])
l2 = list(letters[6:10])
df = data.frame(a=1:5)
df$x1= c("a", "b", "g", l1, l2)
正如我们所料,使用 for 循环无法匹配嵌套列表的元素:
df$x2 <- NA
for(id in 1:nrow(myData)){
df$x2[df$x1 %in% myData$x1[id]] <- myData$x2[id]
}
输出:
df
a x1 x2
1 1 a za
2 2 b <NA>
3 3 g zg
4 4 a, b, c, d, e <NA>
5 5 f, g, h, i, j <NA>
使用 dplyr:
df %>%
left_join(myData)
抛出错误:
Joining by: c("x1", "x2")
Error: cannot join on column 'x1'
我认为解决方案需要取消列出嵌套列表,但还没有整理出如何将 unlist 函数工作到上述策略中。
我也尝试过使用 data.table 包进行上述操作。如何使用 data.table 完成此操作可能是一个额外的问题。但是,就 data.table 处理数据框中的列表而言,我想将其包含在内,因为它可能提供最佳解决方案。
我的实际数据大约是 100,000 行,因此在列表中匹配以 R 为基数的列表可能会影响性能(考虑 data.table 的另一个原因?)
Fwiw,在数据帧中使用嵌套列表(和其他结构)是我在 Python 中经常做的事情,而且可能有更好的方法首先在 R 中构造数据。
想法?
【问题讨论】:
-
这个问题呼唤我。它说:“使用 rapply。它可能不是最快的。它可能不是最干净的。它可能不是最容易理解的。但它会是最酷的。”
-
或许,最好把你的数据改成一个很长的“data.frame”
DF = data.frame(a = rep(df$a, sapply(df$x1, length)), x1 = unlist(df$x1))并对其进行操作。对于您正在尝试做的事情,merge(merge(DF, myData, by = "x1", all.x = T)) 很有用,如果您真的想要您拥有的格式,您可以使用aggregate来压缩您的长数据。通常,R 可以轻松处理具有多个分类变量的数据,而不是用于最终目标的嵌套列表。
标签: r dataframe data.table dplyr