5

这是(一小部分)数据框“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 型方式:

也许与 apply(df, 1, ...) ?

还是 ddply ?

感谢您的帮助……</p>

4

3 回答 3

6

Matrix indexing to the rescue! R has a way of doing exactly what you are describing. It is simple and powerful but surprisingly little-known.

df$vsel <- df[cbind(1:nrow(df), df$indx)]
于 2012-08-03T14:01:59.730 回答
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.

于 2012-08-03T13:40:26.870 回答
1

你可以这样做:

f <- function(i){df[i,df[i,]$indx]}
temp <- sapply(FUN=f,X=1:length(df[,1]))
cbind(df,vsel=temp)
于 2012-08-03T13:26:06.077 回答