使用值填充行,直到列索引保存在dataframe变量中

时间:2015-04-19 01:00:46

标签: r

我正在尝试使用R中的数据框解决一个小问题。我的数据框Base看起来像这样(我在最后一面添加了dput()版本):

   ID I1 I2 I3 Col
1 001  0  2  1   2
2 002  1  2 NA   3
3 003  3  2 NA   1

我的数据框有一个id变量,数值变量(I1,I2,I3)和一个名为Col的索引变量。我希望从1列开始填充值为I1的所有行,直到其索引保存在Col中的列。例如,在第二行Col显示值为3的情况下,使用1的填充过程应从列I1开始,直到列I3。相同的逻辑应用于其他行。我尝试过这个解决方案,但它不起作用:

Base[-1] <- apply(Base[2:5],1,function(x) {x[1:x[4]]=1})

因为此代码使用1填充所有行,而不考虑Col中保存的索引列。有了这段代码,我得到了这个:

   ID I1 I2 I3 Col
1 001  1  1  1   1
2 002  1  1  1   1
3 003  1  1  1   1

我想得到一个这样的数据框:

   ID I1 I2 I3 Col
1 001  1  1  1   2
2 002  1  1  1   3
3 003  1  2 NA   1

另外,我尝试在x[1:x[4]]=1内更改函数内的x[1:x[x[4]]]=1,但它不起作用。 dput()的{​​{1}}版本是下一个:

Base

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

一种方法是创建行的矩阵,将要更改为一的值的col索引。然后,您可以使用此矩阵来子集和替换data.frame中的值。例如

idx <- do.call(rbind, Map(function(a,b) 
    cbind(a,match(paste0("I",1:b), colnames(Base))), 
    seq_along(Base$Col), Base$Col))

Base[idx]<-1

给出了

   ID I1 I2 I3 Col
1 001  1  1  1   2
2 002  1  1  1   3
3 003  1  2 NA   1

根据需要。

但回到原来的尝试,问题是矢量回收(和错误换位)。当您执行作业(x<-1)时,返回的值是右侧值(1)。该值最终会被回收以填充色谱柱的长度。您希望从函数中返回全长(已转换)x,而不仅仅是您替换的值。您传递给apply的函数不会进行更改,它希望返回新值。所以你可以做到

Base[-1] <- t(apply(Base[2:5],1,function(x) {x[1:x[4]]=1; x}))

Base[-1] <- t(apply(Base[2:5],1,function(x) {replace(x,1:x[4],1)}))

由于t()返回值的方式,我还必须添加apply()来转置返回的矩阵。

答案 1 :(得分:0)

这可以通过row/column索引

来完成
Base[-1][cbind(rep(1:nrow(Base), Base$Col), sequence(Base$Col))] <- 1
Base
#   ID I1 I2 I3 Col
#1 001  1  1  1   2
#2 002  1  1  1   3
#3 003  1  2 NA   1