以下是数据框“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?
感谢您的帮助......
答案 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
会将所有内容转换为字符串。