这个需求还是很常见的,因为我们在处理数据的时候无法全面考虑到数据框中含有哪些类型的数据,比如含有NA、NaN或Inf,甚至是一些乱七八糟的字符串。这时不论做统计分析还是作图,都会带来意想不到的错误。为防止这种现象发生,有必要在分析数据前将这些含有特殊字符的行去掉。

1. 去掉指定列中包含NA/Inf/NaN的行

#如果只是包含NA/Inf/NaN,读入都是视为数值
d <- data.frame(x=c(NA,2,3,Inf,-Inf,NaN),y=c(1,Inf,6,NA,4,NaN))
d
str(d) > d
x y
1 NA 1
2 2 Inf
3 3 6
4 Inf NA
5 -Inf 4
6 NaN NaN 'data.frame': 6 obs. of 2 variables:
$ x: num NA 2 3 Inf -Inf ...
$ y: num 1 Inf 6 NA 4 ...

单独去掉:

> d[!is.na(d$x),] #去掉NA和NaN
x y
2 2 Inf
3 3 6
4 Inf NA
5 -Inf 4 > d[!is.nan(d$x),] #去掉NaN
x y
1 NA 1
2 2 Inf
3 3 6
4 Inf NA
5 -Inf 4 > d[!is.infinite(d$x),] #去掉Inf
x y
1 NA 1
2 2 Inf
3 3 6
6 NaN NaN

一次去掉:

> d[is.finite(d$x),]  #去掉Inf、NA和NaN,推荐
x y
2 2 Inf
3 3 6 > d[!is.na(d$x)&!is.nan(d$x)&!is.infinite(d$x),]
x y
2 2 Inf
3 3 6

2. 去掉指定列中包含其他乱七八糟字符串的行

如果除了以上三种,还包含其他乱七八糟的字符(一般读入时默认这一列就是因子类型),比如:

d <- data.frame(x=c(NA,2.0,3.3,0.2,4,Inf,NaN,"*","$","#"),y=c(1,NA,4,"*",'&',2,3,4,2,1))
> d
x y
1 <NA> 1
2 2 <NA>
3 3.3 4
4 0.2 *
5 4 &
6 Inf 2
7 NaN 3
8 * 4
9 $ 2
10 # 1
> str(d)
'data.frame': 10 obs. of 2 variables:
$ x: Factor w/ 9 levels "#","$","*","0.2",..: NA 5 6 4 7 8 9 3 2 1
$ y: Factor w/ 6 levels "&","*","1","2",..: 3 NA 6 2 1 4 5 6 4 3

去掉NA还是可以同上:

> d[!is.na(d$x),]
x y
2 2 <NA>
3 3.3 4
4 0.2 *
5 4 &
6 Inf 2
7 NaN 3
8 * 4
9 $ 2
10 # 1

但NaN和Inf就不行了,因为is.nan和is.infinite函数只识别数值型。

> d[!is.nan(d$x),]
x y
1 <NA> 1
2 2 <NA>
3 3.3 4
4 0.2 *
5 4 &
6 Inf 2
7 NaN 3
8 * 4
9 $ 2
10 # 1 > d[!is.infinite(d$x),]
x y
1 <NA> 1
2 2 <NA>
3 3.3 4
4 0.2 *
5 4 &
6 Inf 2
7 NaN 3
8 * 4
9 $ 2
10 # 1 > d[is.finite(d$x),]
x y
2 2 <NA>
3 3.3 4
4 0.2 *
5 4 &
6 Inf 2
7 NaN 3
8 * 4
9 $ 2
10 # 1

如果硬要这么干,就要进行类型转换,注意因子转数值需要字符做桥梁哦~

> d[!is.nan(as.numeric(as.character(d$x))),]
x y
1 <NA> 1
2 2 <NA>
3 3.3 4
4 0.2 *
5 4 &
6 Inf 2
8 * 4
9 $ 2
10 # 1
Warning message:
In `[.data.frame`(d, !is.nan(as.numeric(as.character(d$x))), ) :
NAs introduced by coercion > d[!is.infinite(as.numeric(as.character(d$x))),]
x y
1 <NA> 1
2 2 <NA>
3 3.3 4
4 0.2 *
5 4 &
7 NaN 3
8 * 4
9 $ 2
10 # 1
Warning message:
In `[.data.frame`(d, !is.infinite(as.numeric(as.character(d$x))), :
NAs introduced by coercion > d[is.finite(as.numeric(as.character(d$x))),]
x y
2 2 <NA>
3 3.3 4
4 0.2 *
5 4 &
Warning message:
In `[.data.frame`(d, is.finite(as.numeric(as.character(d$x))), ) :
NAs introduced by coercion

警告信息可以看到,乱七八糟字符强制转换数值视为NA了。因为数据量足够大的时候,我们无法知道数据里还含有什么妖魔鬼怪,这时可以只识别数字来提取(不包含NA、Inf和NaN):

t <- grep("^\\d+$",as.character(d$x))
#as.numeric(as.character(d$x[t]))
d[t,] #这里还是因子型,根据需要再转换为数值 > t
[1] 2 5
> d[t,]
x y
2 2 <NA>
5 4 &

3. 去掉整个数据框中包含非数值的行

如果我们是针对整个数据框去除包含非数值的行?

只包含NA、NaN和Inf的情况

d <- data.frame(x=c(NA,2,3,Inf,-Inf,NaN),y=c(1,Inf,6,NA,4,NaN))
> na.omit(d)
x y
3 3.3 4
4 0.2 *
5 4 &
6 Inf 2
7 NaN 3
8 * 4
9 $ 2
10 # 1 > d[!is.nan(rowSums(d)),]
x y
1 NA 1
2 2 Inf
3 3 6
4 Inf NA
5 -Inf 4 > d[!is.infinite(rowSums(d)),] #为啥还有一个Inf的行?
x y
1 NA 1
3 3 6
4 Inf NA
6 NaN NaN > d[is.finite(rowSums(d)),] #去掉Inf、NA和NaN,推荐
x y
3 3 6

或者使用R包IDPmisc::NaRv来处理:

> require(IDPmisc)
> NaRV.omit(d)
x y
3 3 6

针对其他字符情况

我自己随便写的:

> index <- apply(d,1,function(x){grepl("^\\d+$",as.character(x))})
> index
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] FALSE TRUE TRUE FALSE FALSE FALSE
[2,] TRUE FALSE TRUE FALSE TRUE FALSE > d[apply(index,2,function(x)all(x)),]
x y
3 3 6

4. 总结下推荐用法

  • 指定列,且只含有NA/Inf/NaN:
d[is.finite(d$x),]
  • 指定列,含有其他字符:
d[is.finite(as.numeric(as.character(d$x))),]
  • 不指定列,且只含有NA/Inf/NaN:
d[is.finite(rowSums(d)),]

IDPmisc::NaRV.omit(d)
  • 不指定列,含有其他字符:
index <- apply(d,1,function(x){grepl("^\\d+$",as.character(x))})
d[apply(index,2,function(x)all(x)),]

Ref:https://stackoverflow.com/questions/15773189/remove-na-nan-inf-in-a-matrix

https://www.thinbug.com/q/25276155

【R】如何去掉数据框中包含非数值的行?的更多相关文章

  1. 用R语言提取数据框中日期对应年份(列表转矩阵)

    用R语言提取数据框中日期对应年份(列表转矩阵) 在数据处理中常会遇到要对数据框中的时间做聚类处理,如从"%m/%d/%Y"中提取年份. 对应操作为:拆分成列表——列表转矩阵——利用 ...

  2. R语言数据框中,用0替代NA缺失值

    1.用0替代数据框中的缺失值NA 生成数据框: > m <- matrix(sample(c(NA, :), , replace = TRUE), ) > d <- as.da ...

  3. R语言学习——数据框

    > #数据框可以包含不同模式(数值型.字符型.逻辑型等)的数据,是R中最常处理的数据结构.数据框可以通过函数data.frame()创建:mydata<-data.frame(coll,c ...

  4. MFC 编辑框中字体大小改变,行高不能改变,只能显示一半的问题,已解决。

    CKagulaCEdit是CEdit的一个继承类,m_edit的CKagulaCEdit类型的一个变量 调用的时候,是这样的: 编辑框中字体大小改变,行高不能改变,只能显示一半的问题,问题如下: 这时 ...

  5. Python中dataframe数据框中选择某一列非空的行

    利用pandas自带的函数notnull可以很容易判断某一列是否为null类型,但是如果这一列中某一格为空字符串"",此时notnull函数会返回True,而一般我们选择非空行并不 ...

  6. 在javaScript中把非数值类型的数据自动转换为数值类型的两种方式

    一.使用Number()函数. 二.使用parseInt()/parseFloat()函数. 详情: 一.使用Number()函数将非数值类型的数据自动的转化为数组类型 Number()函数可以将任何 ...

  7. R: data.frame 数据框的:查询位置、排序(sort、order)、筛选满足条件的子集。。

    ################################################### 问题:数据框 data.frame 查.排序等,   18.4.27 怎么对数据框 data.f ...

  8. 2-7 R语言基础 数据框

    #数据框 > df <- data.frame(id=c(1,2,3,4),name=c("a","b","c","d ...

  9. R语言中将数据框(data.frame)中字符型数据转化为数值型

    as.data.frame(lapply(data,as.numeric))

随机推荐

  1. 第二次Scrum Metting

    日期:2021年4月25日会议主要内容概述:前后端针对WebAPI进行协调与统一工作,商量接下来两日计划:敲定部分设计细节. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中 ...

  2. 2020BUAA软工热身作业

    2020BUAA软工热身作业 17373010 杜博玮 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 热身作业 我在这个课程的目标是 学习软件工 ...

  3. 【STM32学习笔记】USART 硬件流控

    流控的概念源于 RS232 这个标准,在 RS232 标准里面包含了串口.流控的定义.大家一定了解,RS232 中的"RS"是Recommend Standard 的缩写,即&qu ...

  4. MyBatis源码分析(四):SQL执行过程分析

    一.获取Mapper接口的代理 根据上一节,Mybatis初始化之后,利用sqlSession(defaultSqlSession)的getMapper方法获取Mapper接口 1 @Override ...

  5. 视频编码GOP

    GOP group of pictures GOP 指的就是两个I帧之间的间隔. 比较说GOP为120,如果是720 p60 的话,那就是2s一次I帧. 在视频编码序列中,主要有三种编码帧:I帧.P帧 ...

  6. Oracle 扩容表空间

    system用户登陆oracle https://blog.csdn.net/zyingpei/article/details/88870693 首先查看表空间对应的数据文件位置以及大小 select ...

  7. Redis去重方法

    目录 1.基于 set 2.基于 bit 3.基于 HyperLogLog 4. 基于bloomfilter 这篇文章主要介绍了Redis实现唯一计数的3种方法分享,本文讲解了基于SET.基于 bit ...

  8. 字符串可以这样加索引,你知吗?《死磕MySQL系列 七》

    系列文章 三.MySQL强人"锁"难<死磕MySQL系列 三> 四.S 锁与 X 锁的爱恨情仇<死磕MySQL系列 四> 五.如何选择普通索引和唯一索引&l ...

  9. if语句和switch语句的选择与区别

    if语句和Switch语句的选择 if 结构 基本if选择结构: 处理单一或组合条件的情况 if-else选择结构:处理简单的条件分支情况 多重if选择结构:处理复杂的条件分支情况 嵌套if选择结构: ...

  10. js 实现匀速移动

    js 实现匀速移动 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...