2012-08-03 77 views
4

這裏是(一小部分)的數據幀「DF」與通過拾取在其他列的值創建新的數據幀列根據索引列

和索引列「indx」(其中1 < = indx < = 11)。

「INDX」是通過另一個數據幀中的前一步驟中獲得,然後合併,「DF」:

> df 
    v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 indx 
1 223 0 95 605 95 0 0 0 0 189 0 10 
2 32 0 0 32 0 26 0 0 0 32 0 6 
3 0 0 127 95 64 32 0 0 0 350 0 10 
4 141 0 188 0 361 0 0 0 0 145 0 3 
5 32 0 183 0 127 0 0 0 0 246 0 3 
6 67 0 562 0 0 0 0 0 0 173 0 3 
7 64 0 898 0 6 0 0 0 0 0 0 3 
8 0 0 16 0 32 0 0 0 0 55 0 10 
9 0 0 165 0 0 0 312 0 0 190 0 10 
10 0 0 210 0 0 0 190 0 0 11 0 7 

我需要建立一個新的列「VSEL」,其值是「V(INDX )」

(即,對於1RST行:VSEL = 189因爲INDX = 10和V10 = 189)

我成功地通過使用獲得該結果 「for」 循環:

> df 
    v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 indx vsel 
1 223 0 95 605 95 0 0 0 0 189 0 10 189 
2 32 0 0 32 0 26 0 0 0 32 0 6 26 
3 0 0 127 95 64 32 0 0 0 350 0 10 350 
4 141 0 188 0 361 0 0 0 0 145 0 3 188 
5 32 0 183 0 127 0 0 0 0 246 0 3 183 
6 67 0 562 0 0 0 0 0 0 173 0 3 562 
7 64 0 898 0 6 0 0 0 0 0 0 3 898 
8 0 0 16 0 32 0 0 0 0 55 0 10 55 
9 0 0 165 0 0 0 312 0 0 190 0 10 190 
10 0 0 210 0 0 0 190 0 0 11 0 7 190 

的代碼是:

df$vsel = NA 
for (i in seq(1:nrow(df)) ) 
{ 
    r = df[i,] 
    ind = r$indx 
    df[i,"vsel"] = r[ind] 
} 

...我想避免這種循環(當數據幀是很大的,因爲它是相當緩慢)。

有可能是一個(快)R型方式:

與應用(DF,1,...)

可能?

或ddply?

感謝您的幫助......

回答

1

你可以這樣做:

f <- function(i){df[i,df[i,]$indx]} 
temp <- sapply(FUN=f,X=1:length(df[,1])) 
cbind(df,vsel=temp) 
1

這裏是一個完全量化的解決方案,是很難在速度方面被擊敗。

df$vsel <- as.matrix(df)[1:nrow(df) + nrow(df)*(df$indx-1)] 

這利用了矩陣內部存儲爲長向量(列明智)的事實。 1:nrow(df)將由此指定行和nrow(df)*(df$indx-1)列。如果您在df中混合使用數據類型,那麼這將不起作用,因爲所有內容都將被as.matrix轉換爲字符串。

+0

3個答案都很順利!非常感謝大家。 – Phil 2012-08-03 15:00:47

5

矩陣索引到救援! R有一種方法來完成你所描述的內容。這是簡單而強大的,但令人驚訝的是鮮爲人知。

df$vsel <- df[cbind(1:nrow(df), df$indx)] 
+0

這太神奇了!你有鏈接到這個命令的進一步說明嗎? – nassimhddd 2012-08-03 14:31:10

+0

運行'?「[」'獲取幫助頁面。這確實是一個有用的提示,我不知道'''可以做到這一點。 – Backlin 2012-08-03 15:14:52