我是R的新手,我试图使用for循环删除许多列
for (i in 15:ncol(DB)){
BD[,i]<- NULL
}
但我继续犯这个错误:
Error in `[<-.data.frame`(`*tmp*`, , i, value = NULL) :
new columns would leave holes after existing columns
有人可以解释为什么会这样吗? 感谢
答案 0 :(得分:6)
其他人已经展示了如何做你想做的事情,我将重点关注错误信息的含义以及你的方法无效的原因。
假设您的数据框有20列。循环的第一次迭代将删除第15列,并且在此过程中将在15之后移动所有列以填充间隙,因此第16列的内容现在位于第15列的位置,而数据框现在具有19列。
第二次迭代现在将删除位于第16位的列(最初是第17列)并移动另一列,以便现在有18列。
第三次迭代将删除第17个位置的列(最初第19列已移动两次)并将第20列向下移动到第17个位置,数据框现在有17列。
第4次迭代将尝试将NULL分配给第18列,该列不存在,但是在现有列旁边,因此可能不会抱怨。
第5次迭代现在将尝试分配到第19列,但数据帧中只剩下17列,这将留下间隙(没有第18列),因此会出错。
这可能不是您想要的结果,因为第16列和第18列仍在数据框中,只是位于不同的位置。这是在修改循环中的任何对象时需要小心的原因之一。对于简单删除,其他答案显示更好的方法。但是如果你想使用循环,因为你只是有条件地删除,那么它仍然可能,你只需要使用ncol(DB):15
代替{{1来向后工作(从右到左,从高到低) }}。这从最后一列开始向下移动,这样任何移位的列都是已经过测试和处理的列。
答案 1 :(得分:2)
执行此操作不需要for
循环。只需使用list(NULL)
(破坏性地)删除要删除的列。
示例:
mydf <- data.frame(matrix(1:20, ncol = 10))
mydf
# X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
# 1 1 3 5 7 9 11 13 15 17 19
# 2 2 4 6 8 10 12 14 16 18 20
mydf[4:7] <- list(NULL)
mydf
# X1 X2 X3 X8 X9 X10
# 1 1 3 5 15 17 19
# 2 2 4 6 16 18 20
答案 2 :(得分:1)
虽然我不确定它是不错的风格,但您也可以使用负数指数作为要排除的指数的简写,我经常这样做。
mydf <- data.frame(matrix(1:20, ncol = 10))
mydf
# X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
# 1 1 3 5 7 9 11 13 15 17 19
# 2 2 4 6 8 10 12 14 16 18 20
mydf[,-(4:7)] ## columns 4 through 7 are excluded
# X1 X2 X3 X8 X9 X10
# 1 1 3 5 15 17 19
# 2 2 4 6 16 18 20
如果使用负数指数,请注意操作顺序,因为:
优先于-
,因此-4:7
给出了
mydf[,-4:7]
# Error in .subset(x, j) : only 0's may be mixed with negative subscripts