删除data.frame中具有全部或部分NA(缺失值)的行
我想删除此数据框中的行:
a) 在所有列中包含NA
。 以下是我的示例数据框。
gene hsap mmul mmus rnor cfam
1 ENSG00000208234 0 NA NA NA NA
2 ENSG00000199674 0 2 2 2 2
3 ENSG00000221622 0 NA NA NA NA
4 ENSG00000207604 0 NA NA 1 2
5 ENSG00000207431 0 NA NA NA NA
6 ENSG00000221312 0 1 2 3 2
基本上,我想获取如下数据框。
gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
6 ENSG00000221312 0 1 2 3 2
b) 仅在某些列中包含NA
,因此我也可以得到以下结果:
gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
4 ENSG00000207604 0 NA NA 1 2
6 ENSG00000221312 0 1 2 3 2
#1楼
如果您想更好地控制如何将行视为无效的另一种选择是
final <- final[!(is.na(final$rnor)) | !(is.na(rawdata$cfam)),]
使用上面的代码,这是:
gene hsap mmul mmus rnor cfam
1 ENSG00000208234 0 NA NA NA 2
2 ENSG00000199674 0 2 2 2 2
3 ENSG00000221622 0 NA NA 2 NA
4 ENSG00000207604 0 NA NA 1 2
5 ENSG00000207431 0 NA NA NA NA
6 ENSG00000221312 0 1 2 3 2
成为:
gene hsap mmul mmus rnor cfam
1 ENSG00000208234 0 NA NA NA 2
2 ENSG00000199674 0 2 2 2 2
3 ENSG00000221622 0 NA NA 2 NA
4 ENSG00000207604 0 NA NA 1 2
6 ENSG00000221312 0 1 2 3 2
...仅删除第5行,因为它是唯一包含rnor
和cfam
NA的行。 然后可以更改布尔逻辑以适合特定要求。
#2楼
这将返回至少具有一个非NA值的行。
final[rowSums(is.na(final))<length(final),]
这将返回至少具有两个非NA值的行。
final[rowSums(is.na(final))<(length(final)-1),]
#3楼
我们也可以为此使用子集功能。
finalData<-subset(data,!(is.na(data["mmul"]) | is.na(data["rnor"])))
这样只会给出mmul和rnor中都没有NA的那些行
#4楼
如果要控制每行有效的NA数量,请尝试使用此功能。 对于许多调查数据集,太多的空白问题答案可能会破坏结果。 因此,它们会在某个阈值之后被删除。 此功能将允许您选择在删除行之前可以拥有多少个NA:
delete.na <- function(DF, n=0) {DF[rowSums(is.na(DF)) <= n,]
}
默认情况下,它将消除所有NA:
delete.na(final)gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
6 ENSG00000221312 0 1 2 3 2
或指定允许的最大NA数:
delete.na(final, 2)gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
4 ENSG00000207604 0 NA NA 1 2
6 ENSG00000221312 0 1 2 3 2
#5楼
我是合成器:)。 在这里,我将答案合并为一个函数:
#' keep rows that have a certain number (range) of NAs anywhere/somewhere and delete others
#' @param df a data frame
#' @param col restrict to the columns where you would like to search for NA; eg, 3, c(3), 2:5, "place", c("place","age")
#' \cr default is NULL, search for all columns
#' @param n integer or vector, 0, c(3,5), number/range of NAs allowed.
#' \cr If a number, the exact number of NAs kept
#' \cr Range includes both ends 3<=n<=5
#' \cr Range could be -Inf, Inf
#' @return returns a new df with rows that have NA(s) removed
#' @export
ez.na.keep = function(df, col=NULL, n=0){if (!is.null(col)) {# R converts a single row/col to a vector if the parameter col has only one col# see https://radfordneal.wordpress.com/2008/08/20/design-flaws-in-r-2-%E2%80%94-dropped-dimensions/#commentsdf.temp = df[,col,drop=FALSE]} else {df.temp = df}if (length(n)==1){if (n==0) {# simply call complete.cases which might be fasterresult = df[complete.cases(df.temp),]} else {# credit: http://stackoverflow.com/a/30461945/2292993log <- apply(df.temp, 2, is.na)logindex <- apply(log, 1, function(x) sum(x) == n)result = df[logindex, ]}}if (length(n)==2){min = n[1]; max = n[2]log <- apply(df.temp, 2, is.na)logindex <- apply(log, 1, function(x) {sum(x) >= min && sum(x) <= max})result = df[logindex, ]}return(result)
}
#6楼
对于您的第一个问题,我有一个适合摆脱所有NA的代码。 感谢@Gregor使它更简单。
final[!(rowSums(is.na(final))),]
对于第二个问题,代码只是先前解决方案的替代。
final[as.logical((rowSums(is.na(final))-5)),]
注意-5是数据中的列数。 这将消除具有所有NA的行,因为rowSums总计为5,并且在相减后变为零。 这一次,逻辑上是必要的。
#7楼
tidyr
有一个新函数drop_na
:
library(tidyr)
df %>% drop_na()
# gene hsap mmul mmus rnor cfam
# 2 ENSG00000199674 0 2 2 2 2
# 6 ENSG00000221312 0 1 2 3 2
df %>% drop_na(rnor, cfam)
# gene hsap mmul mmus rnor cfam
# 2 ENSG00000199674 0 2 2 2 2
# 4 ENSG00000207604 0 NA NA 1 2
# 6 ENSG00000221312 0 1 2 3 2
#8楼
假设dat
为数据框,则可以使用以下命令获得预期的输出
1. rowSums
> dat[!rowSums((is.na(dat))),]gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
6 ENSG00000221312 0 1 2 3 2
2. lapply
> dat[!Reduce('|',lapply(dat,is.na)),]gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
6 ENSG00000221312 0 1 2 3 2
#9楼
使用dplyr包,我们可以按以下方式过滤NA:
dplyr::filter(df, !is.na(columnname))
#10楼
尝试na.omit(your.data.frame)
。 至于第二个问题,请尝试将其发布为另一个问题(为清楚起见)。
#11楼
还检查complete.cases
:
> final[complete.cases(final), ]gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
6 ENSG00000221312 0 1 2 3 2
na.omit
对于删除所有NA
来说更好。 complete.cases
通过仅包含数据帧的某些列来允许部分选择:
> final[complete.cases(final[ , 5:6]),]gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
4 ENSG00000207604 0 NA NA 1 2
6 ENSG00000221312 0 1 2 3 2
您的解决方案无法正常工作。 如果您坚持使用is.na
,那么您必须执行以下操作:
> final[rowSums(is.na(final[ , 5:6])) == 0, ]gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
4 ENSG00000207604 0 NA NA 1 2
6 ENSG00000221312 0 1 2 3 2
但是使用complete.cases
更加清晰,快捷。
#12楼
我更喜欢以下方法来检查行是否包含任何NA:
row.has.na <- apply(final, 1, function(x){any(is.na(x))})
这将返回逻辑向量,其值表示一行中是否存在任何NA。 您可以使用它查看必须删除的行数:
sum(row.has.na)
最后放下
final.filtered <- final[!row.has.na,]
对于使用NA的某些部分过滤行,将变得有些棘手(例如,您可以将'final [,5:6]'馈送到'apply')。 通常,Joris Meys的解决方案似乎更优雅。
#13楼
如果优先考虑性能,请使用data.table
和na.omit()
以及可选参数cols=
。
无论对于所有列还是选择列(OP问题第2部分), na.omit.data.table
都是我基准测试中最快的(请参见下文)。
如果您不想使用data.table
,请使用complete.cases()
。
在data.frame
, complete.cases
比na.omit()
或dplyr::drop_na()
更快。 请注意, na.omit.data.frame
不支持cols=
。
基准结果
这是基准(蓝色), dplyr
(粉红色)和data.table
(黄色)方法的比较,这些方法用于删除100个观测值的名义数据集上的全部或选择丢失的观测值或选择缺失的观测值,这些观测值包含20个数值变量,且独立概率为5%缺失,以及第2部分的4个变量的子集。
您的结果可能会因特定数据集的长度,宽度和稀疏性而异。
注意y轴上的对数刻度。
基准脚本
#------- Adjust these assumptions for your own use case ------------
row_size <- 1e6L
col_size <- 20 # not including ID column
p_missing <- 0.05 # likelihood of missing observation (except ID col)
col_subset <- 18:21 # second part of question: filter on select columns#------- System info for benchmark ----------------------------------
R.version # R version 3.4.3 (2017-11-30), platform = x86_64-w64-mingw32
library(data.table); packageVersion('data.table') # 1.10.4.3
library(dplyr); packageVersion('dplyr') # 0.7.4
library(tidyr); packageVersion('tidyr') # 0.8.0
library(microbenchmark)#------- Example dataset using above assumptions --------------------
fakeData <- function(m, n, p){set.seed(123)m <- matrix(runif(m*n), nrow=m, ncol=n)m[m<p] <- NAreturn(m)
}
df <- cbind( data.frame(id = paste0('ID',seq(row_size)), stringsAsFactors = FALSE),data.frame(fakeData(row_size, col_size, p_missing) ))
dt <- data.table(df)par(las=3, mfcol=c(1,2), mar=c(22,4,1,1)+0.1)
boxplot(microbenchmark(df[complete.cases(df), ],na.omit(df),df %>% drop_na,dt[complete.cases(dt), ],na.omit(dt)), xlab='', main = 'Performance: Drop any NA observation',col=c(rep('lightblue',2),'salmon',rep('beige',2))
)
boxplot(microbenchmark(df[complete.cases(df[,col_subset]), ],#na.omit(df), # col subset not supported in na.omit.data.framedf %>% drop_na(col_subset),dt[complete.cases(dt[,col_subset,with=FALSE]), ],na.omit(dt, cols=col_subset) # see ?na.omit.data.table), xlab='', main = 'Performance: Drop NA obs. in select cols',col=c('lightblue','salmon',rep('beige',2))
)
#14楼
delete.dirt <- function(DF, dart=c('NA')) {dirty_rows <- apply(DF, 1, function(r) !any(r %in% dart))DF <- DF[dirty_rows, ]
}mydata <- delete.dirt(mydata)
上面的函数删除任何列中具有“ NA”的数据框中的所有行,并返回结果数据。 如果要检查多个值,例如NA
和?
将参数dart=c('NA')
更改为dart=c('NA', '?')
#15楼
我的猜测是,这样可以更优雅地解决
m <- matrix(1:25, ncol = 5)m[c(1, 6, 13, 25)] <- NAdf <- data.frame(m)library(dplyr) df %>%filter_all(any_vars(is.na(.)))#> X1 X2 X3 X4 X5#> 1 NA NA 11 16 21#> 2 3 8 NA 18 23#> 3 5 10 15 20 NA
#16楼
一种通用且产生相当可读的代码的方法是在dplyr包( filter_all
, filter_at
, filter_if
)中使用filter
函数及其变体:
library(dplyr)vars_to_check <- c("rnor", "cfam")# Filter a specific list of columns to keep only non-missing entries
df %>% filter_at(.vars = vars(one_of(vars_to_check)),~ !is.na(.))# Filter all the columns to exclude NA
df %>% filter_all(~ !is.na(.))# Filter only numeric columns
df %>%filter_if(is.numeric,~ !is.na(.))
删除data.frame中具有全部或部分NA(缺失值)的行相关推荐
- data.frame中的NA值怎么替换成0 把na变为0 把na变为想要的数 改变na 是否为na is.na()是否为null is.null() is.null() 删除去掉NA的行
data.frame中的NA值怎么替换成0 is.na 假设你的data.frame的名字叫做dat dat[is.na(dat)] <- 0 其他想要匹配的条件类似. 删除任意带NA值的行 删 ...
- R语言处理数据——仅删除全部缺失(全部为NA)的行
仅删除全部缺失(全部为NA)的行或列 代码如下: # 先写成函数的形式,方便调用 removeRowsAllNa <- function(x){x[apply(x, 1, function(y) ...
- 【Python数据分析】利用Python删除EXCEL表格中指定的列数据或行数据
如何利用Python删除EXCEL表格中指定的列数据?今天与大家一起分享一下DataFrame对象的drop()函数,drop()函数可根据标签删除EXCEL表格中的列数据或行数据,其语法格式如下: ...
- git 删除本地仓库中的分支_git常用命令行 新建分支 删除分支 提交
1.查看当前分支: git branch 2.查看所有分支,包含远程分支 : git branch -a 3.新建分支: git checkout -b bug123 4.推送本地分支到远程分支(远程 ...
- 删除JavaScript对象中的元素
参考http://stackoverflow.com/questions/208105/how-to-remove-a-property-from-a-javascript-object 通过dojo ...
- R语言使用na.omit函数删除向量数据中的缺失值(NA值)
R语言使用na.omit函数删除向量数据中的缺失值(NA值) 目录 R语言使用na.omit函数删除向量数据中的缺失值(NA值) R 语言特点 R语言使用na.omit函数删除向量数据中的缺失值(NA ...
- R语言ggplot2可视化:使用geom_line函数将dataframe中数据可视化为时间序列(或折线图)(Time Series Plot From a Data Frame)、添加标题、副标题
R语言ggplot2可视化:使用geom_line函数将dataframe中数据可视化为时间序列(或折线图)(Time Series Plot From a Data Frame).添加标题.副标题. ...
- data.table中选择列与data.frame的区别: This difference to data.frame is deliberate and explained in FAQ 1.1.
太长不看版 data.table格式在调用列时, 加上逗号, 如果是字符串, 加上with=FALSE trait = "yield" dat[,trait,with=F] 使用o ...
- pandas使用dropna函数删除dataframe数据中指定数据列的内容为缺失值的数据行(使用subset参数指定数据列)
pandas使用dropna函数删除dataframe数据中指定数据列的内容为缺失值的数据行(使用subset参数指定数据列) 目录
最新文章
- 实现Windows non-Unicode设置批量修改
- SQL Server 2005“备份集中的数据库备份与现有的数据库不同”解决方法此信息转载自BlueSky's Blog,www.heuupk.com,为尊重无价的知识请保留此版权信息。...
- MySQL设置从库只读模式
- 关于递归和斐波那契数列
- zepto怎么设置宽高_【五个阿道夫】剧本杀测评 | 娱乐流量当道的时代 这个世界怎么了...
- 第1章 数据库系统概论-单元测验-数据库原理及应用
- 基于docker快速搭建自己的域名邮箱,mailu邮件服务器
- TFTPD32不能传输数据的解决与尝试
- unbuntu设置iptables
- ES实现自动补全查询
- 51CTO学院 oracle相关视频地址
- 字节跳动2020秋招笔试题
- 中国大学MOOC-翁恺-C语言程序设计习题集 02-0 到 04-4
- 39. 实战:基于api接口实现视频解析播放(32接口,窗口化操作,可导出exe,附源码)
- EndnoteX9下载及教程
- 西山居剑心数据分析笔面试题
- 物联卡中心:新人必看,关于物联网卡常见的三大问题!
- linux下安装python3报错_linux安装python3
- Geth命令选项介绍
- Could not locate PropertySource: I/O error on GET request for “http://localhost:8888/