2016-08-05 12 views
2

次のデータフレームでは、対応するA、B、またはCの列に一致するD2という新しい列を作成します。たとえば、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

とC2が 'DF [C( "A2"、 "B2"、 "C2")] [CBIND(1:nrow(DF) df $ D)] '十分な柔軟性? – thelatemail

+0

@thelatemail:それは素敵なシングルライナーです。 – Sathish

+0

@thelatemailかわいいですが、私はOPが単純な例を作ったと思います – akrun

答えて

1

我々はbase Rからmax.colで効率的にこれを行うことができます。 'A'、 'B'、 'C​​'列( 'd1')のみの 'olddata'をサブセット化し、 'D'と等しいかどうかを確認してください(長さに合わせて 'D'を複製した後)、max.col 'A1'、 'B2'、 'C​​2'の列が 'A'の後に交互に現れるので、最大要素のインデックスを見つけます(この例ではTRUE、行ごとにTRUE値が1つと仮定します) 、 'B'、 'C​​'、cbindを行シーケンスと組み合わせて、行/列インデックスを作成し、それに基づいて要素を抽出して 'D2'列を作成します。ベース(データセットが非常にメモリを要することができる大きな論理matrixへの変換として大きい場合に効率的であるべきである)

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 

Aわずかに異なるアプローチがlapplyを用いてループ内で別々の列を比較することであろうその上、我々は、A2、B2の対応する列のサブセット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 
関連する問題