tidyverse中filter行筛选时缺失值存在的一个坑

您所在的位置:网站首页 tidyverse包安装好久 tidyverse中filter行筛选时缺失值存在的一个坑

tidyverse中filter行筛选时缺失值存在的一个坑

2023-06-08 04:15| 来源: 网络整理| 查看: 265

大家好,我是邓飞,好久没有更新博客了,是因为好久没有进步了。

之前我认为鲁迅说的对,他在《野草》中写道:“当我沉默着的时候,我觉得充实;我将开口,同时感到空虚”。现在确切的情况是,当我停止更新时,我感到充实和无压力,然后越来越不想更新,最后发现没有什么可写的,一旦我想写点东西,就是特别空虚,腹中空空但是又开始大腹便便,好像肚子里没东西,但是都是肉,成年人的忧伤……

回到正轨,今天我用dplyr的filter质控数据时,出现了我意想不到的结果,本着“学到就要分享、输出是最好的学习”原则,模拟一个数据,介绍一下这个坑,以及如何避免。

1. 首先模拟一套数据set.seed(123) df = data.frame(ID = 1:10, Sex = c("F","F","F","F","NA","F","F","NA","M","M"), y1 = c(rnorm(9),NA)) df

数据如下:

> df ID Sex y1 1 1 F -0.56047565 2 2 F -0.23017749 3 3 F 1.55870831 4 4 F 0.07050839 5 5 NA 0.12928774 6 6 F 1.71506499 7 7 F 0.46091621 8 8 NA -1.26506123 9 9 M -0.68685285 10 10 M NA2. 提取Sex不是F的行

我有三种方法:

第一种,用!=第二种,用! ==第三种,用 ! %in%

示例代码如下:

df %>% filter(Sex != "F") df %>% filter(!Sex == "F") df %>% filter(!Sex %in% "F")

示例结果:

可以看到,三者结果一致。

tidyverse中filter行筛选时缺失值存在的一个坑_数据保存

3. 如果把数据保存到Excel再读取write.xlsx(df,"df_test.xlsx")

tidyverse中filter行筛选时缺失值存在的一个坑_数据_02

读取excel数据:

df = read.xlsx("df_test.xlsx") df

tidyverse中filter行筛选时缺失值存在的一个坑_python_03

4. 诡异的时刻:Excel读取的报错library(tidyverse) df %>% filter(Sex != "F") df %>% filter(!Sex == "F") df %>% filter(!Sex %in% "F")

前两个都是错误的,它自动忽略了NA的行……

tidyverse中filter行筛选时缺失值存在的一个坑_excel_04

只有第三种是正确的:

tidyverse中filter行筛选时缺失值存在的一个坑_数据_05

5. R中构建的数据框没问题,Excel转一圈坏了

就是这么诡异。

完整的代码:

set.seed(123) df = data.frame(ID = 1:10, Sex = c("F","F","F","F","NA","F","F","NA","M","M"), y1 = c(rnorm(9),NA)) df # library(tidyverse) library(openxlsx) df %>% filter(Sex != "F") df %>% filter(!Sex == "F") df %>% filter(!Sex %in% "F") write.xlsx(df,"df_test.xlsx") # 读取数据 df1 = read.xlsx("df_test.xlsx") df1 str(df1) library(tidyverse) df1 %>% filter(Sex != "F") df1 %>% filter(!Sex == "F") df1 %>% filter(!Sex %in% "F")

比较一下两个数据框:R中的事NA,Excel读取的是,

tidyverse中filter行筛选时缺失值存在的一个坑_数据_06

用drop_na处理一下,看是否是缺失值:结果发现,R中我构建向量时用的是"NA",而不是NA,被作为字符,所以用filter !=可以提取NA的行。

tidyverse中filter行筛选时缺失值存在的一个坑_excel_07

6. 重新构建R数据框set.seed(123) df2 = data.frame(ID = 1:10, Sex = c("F","F","F","F",NA,"F","F",NA,"M","M"), y1 = c(rnorm(9),NA)) df2

tidyverse中filter行筛选时缺失值存在的一个坑_python_08

用drop_na试一下,没有问题:

> df2 %>% drop_na(Sex) ID Sex y1 1 1 F -0.4456620 2 2 F 1.2240818 3 3 F 0.3598138 4 4 F 0.4007715 5 6 F -0.5558411 6 7 F 1.7869131 7 9 M -1.9666172 8 10 M NA

用三种方法过滤,试一下:前两种都不理想。

> df2 %>% filter(Sex != "F") ID Sex y1 1 9 M -1.966617 2 10 M NA > df2 %>% filter(!Sex == "F") ID Sex y1 1 9 M -1.966617 2 10 M NA > df2 %>% filter(!Sex %in% "F") ID Sex y1 1 5 0.1106827 2 8 0.4978505 3 9 M -1.9666172 4 10 M NA

结论:filter过滤时,会自动忽略NA的行,所以,用%in%才是靠谱的!!!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3