基于列索引的data.frame数据操作

时间:2014-07-30 07:20:03

标签: r

我有data.frame如下,

A <- sample(1:10,5)
B <- sample(11:20, 5)
C <- sample(21:30, 5)
index <- sample(1:3,5, replace=TRUE)
data <- data.frame(A,B,C,index)

> data
   A  B  C index
1  9 17 30     3
2 10 15 26     2
3  2 19 23     2
4  3 13 29     2
5  8 12 25     2

我想要的输出是

> data$output <- c(30,15,19,13,12)
> data
   A  B  C index output
1  9 17 30     3     30
2 10 15 26     2     15
3  2 19 23     2     19
4  3 13 29     2     13
5  8 12 25     2     12

这个想法是索引表示我想要提取的列数。例如对于第二行,index为2,则输出应为B:15。

3 个答案:

答案 0 :(得分:1)

避免使用例如循环的巧妙技巧是使用矩阵来对数据帧进行子集化。让我们首先生成一个矩阵,指定要提取的“单元格”:

m<-matrix(ncol=2, data=c(as.numeric(rownames(data)), data$index))

现在矩阵m必须是列,第一个用于行索引,第二个用于数据帧的列索引。请注意,如果您的行名不是按升序排列,则可能需要相应地调整as.numeric(rownames(data))部分。但是这个解决方案适用于示例数据。

然后使用此矩阵对数据帧进行子集化,简单如下:

data[m]

应该产生正确的结果。然后,您可以将其分配给输出列的数据框:

data$output<-data[m]

这在[运营商的帮助文件中有记录。请参阅?"[",并注意“当通过[单个参数索引数组时] i可以是具有与x的维数一样多的列的矩阵;然后结果是具有与索引集合对应的元素的向量我的每一行。“。

答案 1 :(得分:1)

data.table方法(应该更有效率)

library(data.table)
setDT(data)[, output := .SD[, index, with = F], by = index]

#     A  B  C index output
# 1:  9 17 30     3     30
# 2: 10 15 26     2     15
# 3:  2 19 23     2     19
# 4:  3 13 29     2     13
# 5:  8 12 25     2     12

答案 2 :(得分:0)

或者,

data$output <- t(data[,-4])[data$index+(0:4)*3] #0:4 denotes 1-(1:nrow(data)); 
                       #3 is ncol(data[,-4])
data$output 
#[1] 30 15 19 13 12