2016-12-06 74 views
1

我有3個未知長度的數據幀。R:比較1個數據幀和另外兩個不同長度的數據幀

數據幀A看起來像這樣:

A1 A2 n 
1 1 2 1 
2 3 2 2 
3 2 4 3 

以類似的方式,數據幀B看起來像這樣:

B1 B2 n 
1 3 4 1 
2 4 1 2 
3 1 3 3 

注意,對於每一行A1,A2,B1,B3是全部不同並且包含從1到4的數字。

最後,我有數據幀C

n C1 
1 1 3 
2 1 1 
3 1 4 
4 2 0 
5 2 2 
6 2 3 
7 3 3 
8 3 0 
9 3 1 

注意,C1的值全部爲0至4。

n柱連接的所有數據幀。我想要做的是檢查C1的值是否位於A數據幀或B中,並且這是爲每個n。並在C1中直接替換它。如果值爲0,它應該保持爲0.這是我期待的結果:

n C1 
1 1 B 
2 1 A 
3 1 B 
4 2 0 
5 2 A 
6 2 A 
7 3 B 
8 3 0 
9 3 B 

我該如何做到這一點?感謝您的輸入。

回答

2

這是一個想法。我們首先merge前兩個數據幀。一旦我們merge,我們現在可以創建一個新的數據幀stack所有列(n除外)。通過(在我們的例子df5)創造這個新的數據幀,我們現在可以match粘貼n - 從df5與粘貼nvalue - 從你的第三個數據幀C1(在我們的例子df4)。一個簡單的gsub操作然後只提取匹配值中的字母。作爲最後一步,我們設置來港爲0

df_all <- merge(df2, df3, by = 'n') 
# n A1 A2 B1 B2 
#1 1 1 2 3 4 
#2 2 3 2 4 1 
#3 3 2 4 1 3 

df5 <- data.frame(n = 1:nrow(df_all), stack(df_all[-1]), stringsAsFactors = FALSE) 
#head(df5) 
# n values ind 
#1 1  1 A1 
#2 2  3 A1 
#3 3  2 A1 
#4 1  2 A2 
#5 2  2 A2 
#6 3  4 A2 
ind <- gsub('\\d+', '', df5$ind)[match(do.call(paste, df4), do.call(paste, df5[-3]))] 
ind[is.na(ind)] <- 0 
ind 
#[1] "B" "A" "B" "0" "A" "A" "B" "0" "B" 
2

另外,略有不同,方法是左外連接兩者ABC第一,然後找到該連接將添加的列等於C1

## Do the left outer joins with merge by n and all.x=TRUE 
out <- merge(merge(C,A,by="n",all.x=TRUE),B,by="n",all.x=TRUE) 
## Loop over rows and extract the name of the column whose value matches C1 
## first define a function to do so 
extract.name <- function(i,out) { 
    j <- which(out$C1[i]==out[i,3:ncol(out)]) 
    if (length(j)==0) return("0") else return(substr(colnames(out)[j[1]+2],1,1))      
} 
## Then, apply it to all rows 
out$C1 <- sapply(1:nrow(out),extract.name,out) 
## Keep only the n and C1 columns as output 
out <- out[,1:2] 
## n C1 
##1 1 B 
##2 1 A 
##3 1 B 
##4 2 0 
##5 2 A 
##6 2 A 
##7 3 B 
##8 3 0 
##9 3 B 

數據:

A <- structure(list(A1 = c(1L, 3L, 2L), A2 = c(2L, 2L, 4L), n = 1:3), .Names = c("A1", 
"A2", "n"), class = "data.frame", row.names = c("1", "2", "3" 
)) 
## A1 A2 n 
##1 1 2 1 
##2 3 2 2 
##3 2 4 3 

B <- structure(list(B1 = c(3L, 4L, 1L), B2 = c(4L, 1L, 3L), n = 1:3), .Names = c("B1", 
"B2", "n"), class = "data.frame", row.names = c("1", "2", "3" 
)) 
## B1 B2 n 
##1 3 4 1 
##2 4 1 2 
##3 1 3 3 

C <- structure(list(n = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), C1 = c(3L, 
1L, 4L, 0L, 2L, 3L, 3L, 0L, 1L)), .Names = c("n", "C1"), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9")) 
## n C1 
##1 1 3 
##2 1 1 
##3 1 4 
##4 2 0 
##5 2 2 
##6 2 3 
##7 3 3 
##8 3 0 
##9 3 1 
相關問題