使用列表条目按列加入/合并R中的两个数据帧

时间:2016-06-08 14:35:27

标签: r join merge data.table dplyr

使用数据框时,将list类型的条目存储在列中有时会很有帮助。我想按该类型的列加入两个数据帧。这是两个这样的数据帧的例子

dfm1 <- structure(list(val1 = 1:5, id = list(c(0.4, 0.5), c(0.4, 0.5), c(0.1, 0.5), 0.4, 0.4)), .Names = c("val1", "id"), row.names = c(NA, -5L), class = "data.frame")

dfm2 <- structure(list(val2 = 7:9, id = list(c(0.4, 0.5), c(0.1, 0.5), 0.4)), .Names = c("val2", "id"), row.names = c(NA, -3L), class = "data.frame")

我想通过名为id的列合并/加入它们,这些列包含list个条目。在这种情况下,每个list都包含一个vector(但它可能包含模型对象或任何东西,因为列表非常灵活)。例如,

> dfm2$id[1]
[[1]]
[1] 0.4 0.5
> class(dfm2$id[1][[1]])
[1] "numeric"
> is.vector(dfm2$id[1][[1]])
[1] TRUE

我无法想到如何将id列加在一起,以便来自val1的{​​{1}}和来自dfm1的{​​{1}}位于同一{ {1}}。当我尝试使用val2时,我得到:

dfm2
  

错误:无法加入列'id'x'id':由于类型不兼容(列表/列表),无法加入'id'x'id'

我对data.frame包裹没有好运:

dplyr
  

forderv(x,by = rightcols)出错:     订购的第一列是“list”类型,尚不支持

这是我想要的输出:

dplyr::left_join(dfm1, dfm2, by = "id")

谢谢你的帮助!如果您有任何建议,“使用一列列表条目是愚蠢的 - 请避免使用并改为执行XXX”,当然,这可能会有所帮助,但我也在寻找这个问题的答案正如我设置的那样: - )

修改我将data.table中的条目从 dt1 <- as.data.table(dfm1) dt2 <- as.data.table(dfm2) dt1[dt2, on = "id"] 更改为desired_dfm <- structure(list(val1 = 1:5, id = list(c(0.4, 0.5), c(0.4, 0.5), c(0.1, 0.5), 0.4, 0.4), val2 = c(7, 7, 8, 9, 9)), .Names = c("val1", "id", "val2"), row.names = c(NA, -5L), class = "data.frame") > desired_dfm val1 id val2 1 1 0.4, 0.5 7 2 2 0.4, 0.5 7 3 3 0.1, 0.5 8 4 4 0.4 9 5 5 0.4 9

澄清编辑评论指出,可以将此dfm2$id[3]变量分散到两列中,然后加入它们。我同意这是可能的,但这是一个简单的例子,并且有更复杂的情况,这种方法可能不会起作用。

1 个答案:

答案 0 :(得分:0)

以下是获得所需输出的非常基本且无灵感的方法。仅当listsfloatsintegersstring个字符时,它才有效。但我认为这有助于你开始:

数据

dfm1 <- structure(list(val1 = 1:5, id = list(c(0.4, 0.5), c(0.4, 0.5), c(0.1, 0.5), 0.4, 0.4)), .Names = c("val1", "id"), row.names = c(NA, -5L), class = "data.frame")

dfm2 <- structure(list(val2 = 7:9, id = list(c(0.4, 0.5), c(0.1, 0.5), 0.4)), .Names = c("val2", "id"), row.names = c(NA, -3L), class = "data.frame")

过程

library(magrittr)

#You need to create new columns of the same name for both of your datasets

dfm1$newcol <- do.call('rbind',lapply(dfm1$id,function(x) paste(x,sep="",collapse="")))

dfm2$newcol <- do.call('rbind',lapply(dfm2$id,function(x) paste(x,sep="",collapse="")))

这里的想法是为id列创建代理,并使用这些代理来合并数据集。此处的代理是通过concatenating(或pasting一起)id列中每行的元素获得的。

#Merge the datasets by 'newcol' and select the needed columns

merged_df <- merge(dfm1, dfm2, by = "newcol", sort=F) %>% subset(.,select=c("val1","id.x","val2"))


merged_df

 val1     id.x val2
    1 0.4, 0.5    7
    2 0.4, 0.5    7
    3 0.1, 0.5    8
    4      0.4    9
    5      0.4    9

如果需要,您可以将id.x列重命名为id以反映原始数据框。

此外,根据str函数,输出的数据框仍然具有id.x类型的list

str(merged_df)
'data.frame':   4 obs. of  3 variables:
 $ val1: int  1 2 4 5
 $ id.x:List of 4
  ..$ : num  0.4 0.5
  ..$ : num  0.4 0.5
  ..$ : num 0.4
  ..$ : num 0.4
 $ val2: int  7 7 9 9

我希望这会有所帮助。