我正在尝试使用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
感谢您的帮助。
答案 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