根据索引列

问题描述:

这里是(一小部分)的数据帧“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?

感谢您的帮助......

你可以这样做:

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

这里是一个完全量化的解决方案,是很难在速度方面被击败。

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

矩阵索引到救援! 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