我有一个脚本,它有一堆质量控制校验和,它被数据集捕获,由于质量控制,无需删除任何样本(行)。但是,这个脚本给了我一个零行数据框的意外结果。使用示例数据,为什么这样做:
data(iris)
##get rid of those pesky factors
iris$Species <- NULL
med <- which(iris[, 1] < 4.9)
medtemp <- iris[-med, ]
dim(medtemp)
[1] 134 4
但这会返回零行的数据框:
small <- which(iris[, 1] < 4.0)
smalltemp <- iris[-small, ]
dim(smalltemp)
[1] 0 4
就像这样:
x <- 0
zerotemp <- iris[-x, ]
dim(zerotemp)
[1] 0 4
似乎smalltemp
数据框应与iris
的大小相同,因为根本没有要删除的行。这是为什么?
答案 0 :(得分:3)
从Patrick Burns的R Inferno p逐字复制。 41(我希望这构成“合理使用” - 如果有人反对我将其删除)
负面什么都不是
> x2 <- 1:4
> x2[-which(x2 == 3)]
[1] 1 2 4
上面的命令返回x2
中不等于3的所有值。
> x2[-which(x2 == 5)]
numeric(0)
希望上面的命令返回所有x2
,因为没有元素
等于5.现实将冲破这种希望。相反,它返回一个长度向量
零。
以下两个陈述之间存在细微差别:
x[]
x[numeric(0)]
输入的细微差别,但输出的差异没有微妙。 原始问题至少有三种可能的解决方案。
out <- which(x2 == 5)
if(length(out)) x2[-out] else x2
另一种解决方案是使用逻辑下标:
x2[!(x2 %in% 5)]
或者,从某种意义上说,你可以向后工作:
x2[ setdiff(seq along(x2), which(x2 == 5)) ]
答案 1 :(得分:2)
不使用which
来获取索引,而是使用布尔向量并对其进行否定。这样你就可以做到这一点:
small <- iris[, 1] < 4.0
smalltemp <- iris[!small, ]
dim(smalltemp)
[1] 150 4
编辑:我认为不允许负0的索引(如你的情况),因为没有第0个索引,因此R不能从你的选择中排除该索引。负索引可以解释为:“给我回去除了那些具有这些索引的行之外的所有行。”
答案 2 :(得分:2)
在你的第二个例子中,small
评估为0?
获取向量的第0个元素将始终返回空向量:
> foo <- 1:3
> foo
[1] 1 2 3
> foo[0]
integer(0)
>
答案 3 :(得分:2)
这是因为如何处理索引为零的规则。只允许严格的正面或严格的负面指数。由于[0]
没有返回任何内容,
R> -0 == 0
[1] TRUE
因此,你没有得到任何你期望掉落的东西。
identical(0)
问题被NULL
视为索引,并且记录为按0
索引,因此行为相同。