与其他data.frame中的行匹配的列表列元素

时间:2018-12-02 00:06:19

标签: r dataframe match

我有以下两个data.frames:

df1 <- data.frame(Var1=c(3,4,8,9),
               Var2=c(11,32,1,7))

> df1
  Var1 Var2
1    3   11
2    4   32
3    8    1
4    9    7

df2 <- data.frame(ID=c('A', 'B', 'C'),
                ball=I(list(c("3","11", "12"), c("4","1"), c("9","32"))))

> df2
  ID      ball
1  A 3, 11, 12
2  B      4, 1
3  C     9, 32

请注意,ball中的列df2是一个列表。

我想选择ID中的df2,其中列ball中的元素与df1中的一行相匹配。

理想的输出如下所示:

> df3
  ID ball1 ball2
1  A     3    11

有人知道如何有效地做到这一点吗?原始数据在两个data.frame中都包含数百万行。

1 个答案:

答案 0 :(得分:1)

data.table解决方案比基础R解决方案的运行速度要快得多,但这是有可能的。

您的数据:

df1 <- data.frame(Var1=c(3,4,8,9),
                  Var2=c(11,32,1,7))
df2 <- data.frame(ID=c('A', 'B', 'C'),
                  ball=I(list(c("3","11", "12"), c("4","1"), c("9","32"))))

过程:

df2$ID <- as.character(df2$ID) # just in case they are levels instead

n <- length(df2)# initialize the size of df3 to be big enough
df3 <- data.frame(ID = character(n),
                  Var1 = numeric(n), Var2 = numeric(n), 
                  stringsAsFactors = F) # to make sure we get the ID as a string
count = 0 # counter
for(i in 1:nrow(df1)){
  for(j in 1:nrow(df2)){
    if(all(df1[i,] %in% df2$ball[[j]])){
      count = count + 1
      df3$ID[count] <- df2$ID[j]
      df3$Var1[count] <- df1$Var1[i]
      df3$Var2[count] <- df1$Var2[i]
    }
  }
}
df3_final <- df3[-which(df3$ID == ""),] # since we overestimated the size of d3
df3_final