在R中删除多列出错

3

我是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 

有人能解释一下为什么会发生这种情况吗?谢谢。

1
只需执行 BD<-BD[, 1:14]。这将保留前14列,无需循环。 - MrFlick
3个回答

6
其他人已经展示了如何实现您想要的功能,我将重点关注错误消息的含义以及为什么您的方法不起作用。
假设您的数据框有20列。第一次循环将删除第15列,并在此过程中将15号之后的所有列向左移动,使原来的第16列现在处于第15列的位置,数据框现在只剩下19列。
第二次循环将删除16号位置上的列(原本是第17列),并将其他列向左移动,此时数据框只剩下18列。
第三次循环将删除17号位置上的列(原本是第19列,因为已经移动了两次),并将第20列移到17号位置,此时数据框只剩下17列。
第四次循环将试图将NULL赋给第18列,但该列不存在,但它与一个现有列相邻,所以可能不会报错。
第五次循环将尝试对第19列进行赋值,但是由于数据框中只剩下17列,这样会产生一个间隙(即没有第18列),从而导致错误。
这可能不是您想要的结果,因为第16列和第18列仍然存在于数据框中,只是位置不同。这是您需要小心修改循环中的任何对象的原因之一。对于简单的删除,其他答案提供了更好的方法。但是,如果您想要使用循环进行有条件的删除,那么仍然是可能的,只需要反向操作(从右到左,从高到低),使用ncol(DB):15而不是15:ncol(DB)。这从最后一列开始并向下移动,这样任何被移动的列都是已经被测试和处理过的列。

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接