R - 使用行中的值来确定要填充字段的列

时间:2014-09-17 00:08:51

标签: r dataframe

例如: 我有一个名为table的数据框:

Cn c1 c2 c3 c4
c3 1  3  5  6
c2 4  6  7  9

我想创建一个新列,其值包含在列中,列名在Cn中,因此它看起来像:

Cn c1 c2 c3 c4 NewCol
c3 1  3  5  6  5
c2 4  6  7  9  6

我的尝试是table$NewCol<-table[,table$Cn]

但是,table$NewCol[1]不是每行返回1个值,而是包含(5,3)的向量,它引用Cn列中的(c3,c2),这意味着对于每一行,所有查找Cn行并将其放入新变量中。

我知道我可以使用循环但是我处理的是700万+记录数据帧,并且循环非常慢。

任何人都有任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

使用mapply在每行和d $ Cn移动时应用[.data.frame

 table$NewCol <- mapply(i = seq_along(d[['Cn']]),
         j= d[['Cn']],
     FUN = function(i,j,x) x[i,j,drop=TRUE],
     MoreArgs=list(x=d))

如果要考虑速度和效率,请使用data.tableset(此循环 效率)

library(data.table)
setDT(d)

for(i in seq_len(nrow(d))){
  set(d,j='newCol', i=i, value= d[[d[['Cn']][i]]][i])
}

答案 1 :(得分:2)

使用所需行和列值的矩阵索引进行提取。 我使用dat作为您的data.frame名称。

dat[-1][cbind(seq_along(dat$Cn),match(as.character(dat$Cn),names(dat[-1])))]
#[1] 5 6

如:

sel <- cbind(seq_along(dat$Cn),match(as.character(dat$Cn),names(dat[-1])))
sel    

#      row  col
#     [,1] [,2]
#[1,]    1    3
#[2,]    2    2

dat[-1][sel]
#[1] 5 6

7M行的时间和4列示例约为0.4秒。

dat2 <- dat[sample(1:2,7e6,replace=TRUE),]
nrow(dat2)
#[1] 7000000
system.time({
  sel <- cbind(seq_along(dat2$Cn),match(as.character(dat2$Cn),names(dat2[-1])))
  dat2$newcol <- dat2[-1][sel]
})
#   user  system elapsed 
#   0.33    0.07    0.39