循环浏览2个数据框以标识联接的相似列

时间:2019-01-14 05:58:24

标签: r

我在这里有2个可重现的数据帧。我正在尝试确定哪一列包含与另一列相似的值。我希望我的代码从每一列中随机选择1个值,并循环遍历df2中的每一列。

df1 <- data.frame(fruit=c("Apple", "Orange", "Pear"), location = c("Japan", "China", "Nigeria"), price = c(32,53,12))
df2 <- data.frame(grocery = c("Durian", "Apple", "Watermelon"), place=c("Korea", "Japan", "Malaysia"), invoice = c("XD1", "XD2", "XD3"))

df1$source <- "DF1"
df2$source <- "DF2"

df1

   fruit location price source
1  Apple    Japan    32    DF1
2 Orange    China    53    DF1
3   Pear  Nigeria    12    DF1

df2  
     grocery    place invoice source
1     Durian    Korea     XD1    DF2
2      Apple    Japan     XD2    DF2
3 Watermelon Malaysia     XD3    DF2

这是我希望在名为df3的新数据帧下获得的输出。

df3
         grocery    place    invoice source
    1     fruit    location     NA    DF1

“源”列将允许用户标识各个列(水果/位置)的来源。 df3的列名称= df2中的列名称,而row1下的值= df1中的列名称。

“杂货店”列与水果匹配,因为存在匹配值,即分别在“位置”和“位置”列中都可以找到“苹果”和“日本”。

谢谢!

2 个答案:

答案 0 :(得分:2)

这可能不是最佳解决方案,而是使用双sapply的一种方法(因为对于df2的每一列,我们都希望在df1中找到相似的列)

sapply(names(df2), function(x) {
     temp <- sapply(names(df1), function(y) 
         if(any(match(df2[[x]], df1[[y]], nomatch = FALSE))) y else NA)
     ifelse(all(is.na(temp)), NA, temp[which.max(!is.na(temp))])
   }
)

# grocery     place     invoice     source 
# "fruit" "location"         NA         NA 

这将为您提供df2中的所有列,其中matchdf1中的列至少为一个值。然后,您可以稍后手动更改source列,因为如果存在一行,您就知道它来自df1

答案 1 :(得分:1)

进行更改。杂乱无章,但行得通。

#create data frame of column combinations
col_combos <- expand.grid(names(df1), names(df2))

#identify like columns
like_cols <- na.omit(col_combos[as.logical(apply(col_combos, 1, function(x) intersect(df1[, x[1] ],df2[, x[2] ]) > 1 )), ])

#match like columns
rbind(names(df2), as.character(like_cols$Var1)[match(names(df2), as.character(like_cols$Var2))])

     [,1]      [,2]       [,3]      [,4]    
[1,] "grocery" "place"    "invoice" "source"
[2,] "fruit"   "location" NA        NA