2017-06-07 77 views
3

我有兩個長度相同(1000)和寬度(200)的數據幀。在這兩個數據框中,每一行都是一個人。在一個數據幀中,每一列都是二進制項目分數(即0或1)。在另一個數據框中,每列都是項目標籤。下面是它:R中的數據匹配

數據幀1:

item1 item2 item3 
0  1  1 
1  0  0 
1  1  1 

數據幀2:

item1 item2 item3 
C2HSD WW11S3 EI22S 
WW11S3 2JDDS TT6SQ1 
EI22S TT6SQ1 331ID 

我要的是一個結合和匹配數據幀是這樣的:

C2HSD WW11S3 EI22S 2JDDS TT6SQ1 331ID 
0  1  1  NA NA  NA 
NA  1  NA 0  0  NA 
NA  NA  1  NA 1  1 

謝謝!

回答

2

我們可以melt兩個數據集,以「長」格式」,做一個left_join,後來它spread爲‘寬VAR2‘

library(reshape2) 
library(tidyverse) 
d1 <- melt(as.matrix(df1)) 
d2 <- melt(as.matrix(df2)) 
left_join(d2, d1, by = c("Var1", "Var2")) %>% 
     select(-Var2) %>% 
     spread(value.x, value.y) %>% 
     select(-Var1) 
# 2JDDS 331ID C2HSD EI22S TT6SQ WW11S 
#1 NA NA  0  1 NA  1 
#2  0 NA NA NA  0  1 
#3 NA  1 NA  1  1 NA 

一個base R選擇’格式取出後’會是replace其中「DF1」值是使用Map 0與NA「DF2」的對應的列的值,然後stack它爲「data.frame」,transform的「值」列,以factor並獲得與頻率3210

un1 <- unique(unlist(df2)) 
table(transform(stack(Map(function(x,y) replace(y, !x, NA), 
    df1, df2))[2:1], values = factor(values, levels = un1))) 
2

在基礎R試圖使用mapplymatch如下。下面的代碼使用match來返回帶有NA的向量,其中一列dat2沒有任何變量,並且在dat2中存在匹配的dat1的相應值。對於所需的輸出結構,必須調換dat1 data.frame(data.frame(t(dat1)))。

# get the vector of unique names in dat2 
vars <- unique(unlist(dat2)) 
mapply(function(x, y, vars) x[match(vars, y)], 
     data.frame(t(dat1)), dat2, MoreArgs=list(vars=vars)) 
    X1 X2 X3 
[1,] 0 NA NA 
[2,] 1 1 NA 
[3,] 1 NA 1 
[4,] NA 0 NA 
[5,] NA 0 1 
[6,] NA NA 1 

返回一個data.frame與命名的變量,在t把這個包,data.framesetNames

setNames(data.frame(t(mapply(function(x, y, vars) x[match(vars, y)], 
          data.frame(t(dat1)), dat2, MoreArgs=list(vars=vars)))), vars) 

    C2HSD WW11S3 EI22S 2JDDS TT6SQ1 331ID 
X1  0  1  1 NA  NA NA 
X2 NA  1 NA  0  0 NA 
X3 NA  NA  1 NA  1  1 

以下數據將dat2作爲字符向量而不是因子。這是此類操作的首選存儲類型。

數據

dat1 <- 
structure(list(item1 = c(0L, 1L, 1L), item2 = c(1L, 0L, 1L), 
    item3 = c(1L, 0L, 1L)), .Names = c("item1", "item2", "item3" 
), class = "data.frame", row.names = c(NA, -3L)) 
dat2 <- 
structure(list(item1 = c("C2HSD", "WW11S3", "EI22S"), item2 = c("WW11S3", 
"2JDDS", "TT6SQ1"), item3 = c("EI22S", "TT6SQ1", "331ID")), .Names = c("item1", 
"item2", "item3"), class = "data.frame", row.names = c(NA, -3L 
))