2016-08-18 7 views
1

forループで簡単に解決できる質問があります。しかし、データフレームに数十万行があるので、これには非常に長い計算時間がかかるため、私は迅速でスマートなソリューションを探しています。各行に対して、セル内の別の値と一致する列名の値を抽出します。

私のデータフレームの行ごとに

、Iは、列名の最初の列(INDEX)からの1つに一致するセルの値を貼り付けたい

データフレームは、この

> mydata 
    INDEX 1 2 3 4 5 6 
1  2 18.9 9.5 22.6 4.7 16.2 7.4 
2  2 18.9 9.5 22.6 4.7 16.2 7.4 
3  2 18.9 9.5 22.6 4.7 16.2 7.4 
4  4 18.9 9.5 22.6 4.7 16.2 7.4 
5  4 18.9 9.5 22.6 4.7 16.2 7.4 
6  5 18.9 9.5 22.6 4.7 16.2 7.4 

ように見えます

mydata <- data.frame(INDEX=c(2,2,2,4,4,5), ONE=(rep(18.9,6)), TWO=(rep(9.5,6)), 
        THREE=(rep(22.6,6)), FOUR=(rep(4.7,6)), FIVE=(rep(16.2,6)), SIX=(rep(7.4,6))) 
colnames(mydata) <- c("INDEX",1,2,3,4,5,6) 

そして、これは、新たに計算された変数を使用して新しいデータフレームである:ここではそれを再生するためのコードです

> new_mydf 
    INDEX 1 2 3 4 5 6 VARIABLE 
3  2 18.9 9.5 22.6 4.7 16.2 7.4  9.5 
2  2 18.9 9.5 22.6 4.7 16.2 7.4  9.5 
1  2 18.9 9.5 22.6 4.7 16.2 7.4  9.5 
5  4 18.9 9.5 22.6 4.7 16.2 7.4  4.7 
4  4 18.9 9.5 22.6 4.7 16.2 7.4  4.7 
6  5 18.9 9.5 22.6 4.7 16.2 7.4  16.2 

ループがにあるように私は、それはここで、以下のforループ使用して、私は上記に書いたように、私は(多分dplyr、または他の機能のようなパッケージを使用して?)もっと簡単な解決策を探しています解決

mydata$VARIABLE<-apply(mydata, 1, function(x) { x[names(x)==x[names(x)=="INDEX"]] }) 

編集:あなたのループに基づいて、私の拡張データセット

id = mydata$INDEX 
new_mydf <- data.frame() 
for (i in 1:length(id)) { 
    mydata_row <- mydata[i,] 
    value <- mydata_row$INDEX 
    mydata_row["VARIABLE"] <- mydata_row[,names(mydata_row) == value] 
    new_mydf <- rbind(mydata_row,new_mydf) 
} 
new_mydf <- new_mydf[ order(new_mydf[,1]), ] 
+0

が、このあります: http://stackoverflow.com/q/33310179/ – Frank

+0

ありがとうございます、data.tableのソリューションもうまくいきます! – refroll

答えて

1

のために遅い、無名関数とapplyのこの使用は、より速く(あなたmydata初期定義を持つ)とすることができ、それもで動作します0文字数:これはapplyよりも速くなりますインデックス、とサブセットを使用しています

new_mydf <- data.frame(mydata, 
         VARIABLE=mydata[cbind(seq_len(nrow(mydata)), 
              match(as.character(mydata$INDEX),colnames(mydata)))]) 

mydata <- data.frame(INDEX=c("B","B","B","D","D","E"), "A"=(rep(18.9,6)), "B"=(rep(9.5,6)), 
       "C"=(rep(22.6,6)), "D"=(rep(4.7,6)), "E"=(rep(16.2,6)), "F"=(rep(7.4,6))) 

mydata$VARIABLE<-apply(mydata, 1, function(x) { x[names(x)==x[names(x)=="INDEX"]] }) 

> mydata INDEX A B C D E F VARIABLE 1 B 18.9 9.5 22.6 4.7 16.2 7.4 9.5 2 B 18.9 9.5 22.6 4.7 16.2 7.4 9.5 3 B 18.9 9.5 22.6 4.7 16.2 7.4 9.5 4 D 18.9 9.5 22.6 4.7 16.2 7.4 4.7 5 D 18.9 9.5 22.6 4.7 16.2 7.4 4.7 6 E 18.9 9.5 22.6 4.7 16.2 7.4 16.2

+0

ありがとうございます。このソリューションはうまくいきます。しかし、オリジナルの拡張データフレームでは、 "1"、 "2"などの文字を使用して列の名前を変更する必要がありました。 – refroll

+0

ようこそ。あなたを助けてくれてありがとう! @aichaoサブセッティングのソリューションは素晴らしいと非常に非常に高速です!もしあなたが非常に巨大なデータセットを持っていれば、それはより良い使い方かもしれません、そして、私はそれが簡単に文字インデックス(因子(INDEX)を使用していますか?) – Toshiro

+0

@Toshiro: INDEXのデータを列名に変換します。 – aichao

1

何をしたいがすることによって達成することができます。たとえば、データセットがある場合:

INDEX Alpha Beta Charlie Delta Epsilon Foxtrot 
1 Beta 18.9 9.5 22.6 4.7 16.2  7.4 
2 Beta 18.9 9.5 22.6 4.7 16.2  7.4 
3 Beta 18.9 9.5 22.6 4.7 16.2  7.4 
4 Delta 18.9 9.5 22.6 4.7 16.2  7.4 
5 Delta 18.9 9.5 22.6 4.7 16.2  7.4 
6 Epsilon 18.9 9.5 22.6 4.7 16.2  7.4 

これが得られます:ベンチマーク

INDEX Alpha Beta Charlie Delta Epsilon Foxtrot VARIABLE 
1 Beta 18.9 9.5 22.6 4.7 16.2  7.4  9.5 
2 Beta 18.9 9.5 22.6 4.7 16.2  7.4  9.5 
3 Beta 18.9 9.5 22.6 4.7 16.2  7.4  9.5 
4 Delta 18.9 9.5 22.6 4.7 16.2  7.4  4.7 
5 Delta 18.9 9.5 22.6 4.7 16.2  7.4  4.7 
6 Epsilon 18.9 9.5 22.6 4.7 16.2  7.4  16.2 

、シミュレートし、より大きなデータセットを:data.tableで

## simulate some data with 1000 columns and 1000 rows 
INDEX <- ceiling(runif(1000,0,1000)) 
data <- rep(runif(1000,0,1), each=1000) 
mydata <- data.frame(INDEX=INDEX,matrix(data,nrow=1000)) 
colnames(mydata) <- c("INDEX", seq_len(1000)) 

## using indexing 
system.time(new_mydf <- data.frame(mydata, VARIABLE=mydata[cbind(seq_len(nrow(mydata)),match(as.character(mydata$INDEX),colnames(mydata)))])) 
## user system elapsed 
## 0.030 0.001 0.031 

## using apply 
system.time(mydata$VARIABLE<-apply(mydata, 1, function(x) { x[names(x)==x[names(x)=="INDEX"]] })) 
## user system elapsed 
## 0.268 0.010 0.291 

## check that we computed the same thing 
all.equal(mydata,new_mydf,check.names=FALSE) 
##[1] TRUE 
関連する問題