通过根据索引列选择其他列中的值来创建新数据框列

时间:2012-08-03 13:14:57

标签: r dataframe

以下是数据框“df”(的一小部分):

11个变量“v1”到“v11”

和索引列“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)”

(即第一行: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?

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

3 个答案:

答案 0 :(得分:6)

矩阵索引救援! R有一种完全按照你所描述的方式做事的方法。 它简单而有力,但却鲜为人知。

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

答案 1 :(得分:1)

你可以这样做:

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

答案 2 :(得分: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会将所有内容转换为字符串。