过滤数据帧时NA的影响

时间:2017-11-20 17:15:42

标签: r dataframe filter

我有一个大型数据框,其中包括以下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行:

  

过滤器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 

如果我对我的过滤方法进行简单的更改并使用'哪个'函数,我会得到我期望的结果。

  

过滤器2:

     

df< - df.bak#恢复原始数据框
  df< - df [(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的预期行为吗?

也许这会帮助别人避免因此而受到影响。谢谢

  

更新:使用mtcars复制问题:

 data(mtcars) 
 set.seed(66)

> nrow(mtcars)
[1] 32

查看“碳水化合物”列分布的细分符合预期,共计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' )

2 个答案:

答案 0 :(得分:2)

  

我对上述内容的解释是过滤器#1引起了预期   300,645行被丢弃但是产生了280,146的副作用   由于df $ AVGsessTOS中存在NA,“空行”。 (300,645 -   280,146 = 20,499)

原则上,subesetting 无法扩展您的数据框。看看下面的例子:

对于数据集:

set.seed(123)
mtcars[sample(1:10, 3), ] <- NA

根据条件mtcars[mtcars$carb > 2, ]过滤值会导致匹配行和NAs

>> 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:为什么R不能理解if(num!= NA)?

     

Peter Dalgaard:因为与未知值的比较会产生未知结果。

     David Winsemius:其他任何东西都会违反热力学第二定律。我们不能比较减少熵,现在我们可以吗?不确定性无法走上坡路。

     

JPM Miao,Peter Dalgaard和David Winsemius(关于为什么需要.na())R-help(2013年5月)

哪些

如果您比较结果,whichwhich 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的行索引,而子集化操作返回三个值NATRUEFALSE

答案 1 :(得分:0)

看起来是吗?我通常不会以这种方式过滤,通常我会使用dplyr

set.seed(123)
df <- data.frame(x = sample(1:5, 100, replace = TRUE), y = sample(c(1, 4, NA), 100, replace = TRUE))

不使用哪个:

> head(df[(df$y < 2),], 10)
      x  y
2     4  1
NA   NA NA
NA.1 NA NA
NA.2 NA NA
10    3  1
NA.3 NA NA
12    3  1
13    4  1
NA.4 NA NA
NA.5 NA NA

使用:

> head(df[which(df$y < 2),], 10)
   x y
2  4 1
10 3 1
12 3 1
13 4 1
16 5 1
22 4 1
23 4 1
24 5 1
27 3 1
28 3 1

我建议您使用head()View()(在RStudio中)调查您的数据框,或以某种方式打印它们。它将有助于回答一些有关想知道发生了什么的问题!