我有一个大型数据框,其中包括以下 2 个字段和显示的行数(为简单起见,仅显示 2 列):
> nrow(df)
[1] 3541393
> summary(df$ttlVisits)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 1.000 1.000 1.527 1.000 118.000
> summary(df$AVGsessTOS)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
1 27 30 115 72 21554 280146
我想删除 AVGsessTOS > 1628 的行
> nrow(df[df$AVGsessTOS>=1628,])
[1] 300645
因此,我运行以下命令,期望删除 300,645 行,但实际得到的是 20,499 行:
FILTER 1:
df <- df[ df$AVGsessTOS < 1628, ]
该命令对行数和 2 个原始列的影响:
> 3541393 - nrow(df)
[1] 20499
> summary(df$ttlVisits)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
1.00 1.00 1.00 1.53 1.00 118.00 280146
> summary(df$AVGsessTOS)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
1.0 27.0 30.0 102.5 70.0 1627.5 280146
如果我对过滤方法进行简单的更改并使用 'which' 函数,我就会得到我期望的结果。
FILTER 2:
df <- df.bak # restore original data frame
df <- df[ which(df$AVGsessTOS < 1628), ]
以及该命令的影响:
> 3541393 - nrow(df)
[1] 300645
> summary(df$ttlVisits)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 1.000 1.000 1.526 1.000 118.000
> summary(df$AVGsessTOS)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.0 27.0 30.0 102.5 70.0 1627.5
我对上述内容的解释是,过滤器 #1 导致预期的 300,645 行被删除,但由于 df$AVGsessTOS 中存在 NA,因此产生了添加 280,146“空行”的副作用。 (300,645 - 280,146 = 20,499)
有人可以确认我对这些结果的解释,并且这是过滤器 #1 的预期行为吗?
也许这也能帮助其他人避免受到影响。谢谢
UPDATE: Replicating the issue with mtcars:
data(mtcars)
set.seed(66)
> nrow(mtcars)
[1] 32
查看“carb”列的分布细目,与预期一致,总计 32:
> table(mtcars$carb)
1 2 3 4 6 8
7 10 3 10 1 1
现在将 3 个碳水化合物值设置为 NA(不是整行,只是碳水化合物值)以创建与我的数据集类似的数据,以说明问题:
set.seed(66)
mtcars[sample(1:nrow(mtcars), 3), ]$carb <- NA
同样,“碳水化合物”列的分布总计 29 与预期一致,比设置 NA 后的原始值少 3:
> table(mtcars$carb)
1 2 3 4 6 8
6 10 1 10 1 1
现在,删除上面显示的 6 行,碳水化合物值为 1
> mtcars2 <- mtcars[mtcars$carb>=2,]
确认预期记录已删除:
> table(mtcars2$carb)
2 3 4 6 8
10 1 10 1 1
但是,行数与上述计数不一致:
> nrow(mtcars2)
26
检查数据显示 3 整行 NA 值。 这些行从哪里来?
View(mtcars2)
( replicate to see output of 'view' )
最佳答案
My interpretation of the above is that Filter #1 caused the expected 300,645 rows to get dropped BUT had a side effect of adding 280,146 "empty rows" due to the presence of NA's in df$AVGsessTOS. ( 300,645 - 280,146 = 20,499)
原则上,子集设置不能扩展您的数据框。看一下下面的示例:
对于数据集:
set.seed(123)
mtcars[sample(1:10, 3), ] <- NA
根据条件mtcars[mtcars$carb > 2, ]
过滤值将产生匹配的行和NA
:
>> mtcars[mtcars$carb > 2, ]
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
NA NA NA NA NA NA NA NA NA NA NA NA
NA.1 NA NA NA NA NA NA NA NA NA NA NA
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
NA.2 NA NA NA NA NA NA NA NA NA NA NA
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
通过 fortunes
提供了更有趣的解释。封装:
fortunes::fortune(which = "is.na")
JPM Miao: Why can't R understand if(num!=NA)?
Peter Dalgaard: Because comparison with an unknown value yields an unknown result.
David Winsemius: Anything else would violate the Second Law of Thermodynamics. We cannot have comparisons reducing entropy, now can we? Uncertainty cannot run uphill.
JPM Miao, Peter Dalgaard, and David Winsemius (on why is.na() is needed) R-help (May 2013)
哪个
至于which
所扮演的角色,which
aims to return index of elements where logical value is TRUE
如果你比较结果:
>> which(mtcars$carb > 2)
[1] 2 7 11 12 13 14 15 16 17 24 29 30 31
>> mtcars$carb > 2
[1] NA TRUE NA NA FALSE FALSE TRUE NA NA NA TRUE TRUE TRUE
[14] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
[27] FALSE FALSE TRUE TRUE TRUE FALSE
which
返回条件为 true 的行索引,而取子集操作返回三个值 NA
、TRUE
和 FALSE
.
关于r - 过滤数据帧时 NA 的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47397528/