2016-08-05 91 views
2

在下面的數據框中,我想創建一個名爲D2的新列,它與相應的A,B或C列匹配。例如,如果D == A,我想D2 == A2。R - 在同一數據幀中與其他列匹配的列

A A2 B B2 C C2 D 
1 10 2 90 3 9 1 
1 11 2 99 3 15 1 
1 42 2 2 3 9 2 
1 5 2 54 3 235 2 
1 13 2 20 3 10 3 
1 6 2 1 3 4 3 

這就是我想要的新數據幀的樣子:

A A2 B B2 C C2 D D2 
1 10 2 90 3 9 1 10 
1 11 2 99 3 15 1 11 
1 42 2 2 3 9 2 2 
1 5 2 54 3 235 2 54 
1 13 2 20 3 10 3 10 
1 6 2 1 3 4 3 4 

我已經成功地使用dplyr與ifelse語句這樣做,但因爲我有很多列這樣做,過了一段時間會變得乏味。我想知道是否有更聰明的方法來完成同樣的任務。

library(dplyr) 

newdata <- olddata %>% mutate(D2=ifelse(D==A,A2,ifelse(D==B,B2,C2))) 
+1

是'DF並[c( 「A2」, 「B2」, 「C2」)] [cbind(1:nrow(DF), df $ D)]'足夠靈活? – thelatemail

+0

@thelatemail:那是一個不錯的單人班輪。 – Sathish

+0

@thelatemail這很可愛,但我認爲OP做了一個簡單的例子 – akrun

回答

1

我們可以有效地用max.colbase R這樣做。只用'A','B','C'列('d1')將'olddata'子集,檢查它是否等於'D'(在複製'D'以匹配長度之後),使用max.col找到最大元素的索引(即在這種情況下爲TRUE,假設每行將有單個TRUE值)乘以2,因爲'A1','B2','C2'列在'A' ,'B','C',cbind與行序列創建行/列索引並基於該索引提取元素以創建'D2'列。

d1 <- olddata[c("A", "B", "C")] 
olddata$D2 <- olddata[cbind(1:nrow(d1), max.col(d1 == rep(olddata["D"], 
      ncol(d1)), "first")*2)] 
olddata$D2 
#[1] 10 11 2 54 10 4 

略微不同的方法將是在使用lapply環路分別比較各列(應該是有效的,如果所述數據集是當轉換到一個大的邏輯matrix可以花費的存儲器非常大),並基於上,我們子集A2,B2,C2的相應列與mapply

i1 <- grep("^[^D]", names(olddata)) #create an index for columns that are not D 
i2 <- seq(1, ncol(olddata[i1]), by = 2)#for subsetting A, B, C 
i3 <- seq(2, ncol(olddata[i1]), by = 2)# for subsetting A2, B2, C2 
olddata$D2 <- c(mapply(`[`, olddata[i3], lapply(olddata[i2], `==`, olddata$D))) 
olddata$D2 
[1] 10 11 2 54 10 4 
相關問題