Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查看R中具有任何NA的所有列名_R_Sapply - Fatal编程技术网

查看R中具有任何NA的所有列名

查看R中具有任何NA的所有列名,r,sapply,R,Sapply,我需要得到至少有1个NA的列的名称 df<-data.frame(a=1:3,b=c(NA,8,6), c=c('t',NA,7)) 但我只需要有NA的变量 我试过这个: sapply(df, function(x) colnames(df[,any(is.na(x))])) 但是我知道所有的列名 names(df)[!!colSums(is.na(df))] #[1] "b" "c" 解释 通过使用,我们正在创建逻辑索引 !colSums(is.na(df)) #here

我需要得到至少有1个NA的列的名称

df<-data.frame(a=1:3,b=c(NA,8,6), c=c('t',NA,7))
但我只需要有NA的变量

我试过这个:

sapply(df, function(x) colnames(df[,any(is.na(x))]))
但是我知道所有的列名

 names(df)[!!colSums(is.na(df))]
 #[1] "b" "c"
解释 通过使用
,我们正在创建逻辑索引

!colSums(is.na(df))   #here the value of `0` will be `TRUE` and all other values `>0` FALSE
 #   a     b     c 
 #TRUE FALSE FALSE 
但是,我们需要选择那些至少有一个
NA
的列,所以
再次否定

!!colSums(is.na(df))
#   a     b     c 
#FALSE  TRUE  TRUE 
并使用此逻辑索引获取至少有一个
NA

基准
set.seed(49)

df1你们非常接近。您的第一次尝试将产生一个
布尔
向量,您可以使用该向量为
df的
名称
建立索引:

contains_any_na = sapply(df, function(x) any(is.na(x)))
names(df)[contains_any_na]
# [1] "b" "c"
更新日期2017年1月14日:自R版本3.1.0起,
anyNA()
可作为
any(is.na()
的替代,上述代码可简化为

names(df)[sapply(df, anyNA)]
# [1] "b" "c"

另一个杂技解决方案(只是为了好玩):

其思想是:获取A中至少有1na的列相当于获取t(A)中至少有NA的行。
完成。根据定义,cases
(非常有效,因为它只是对C函数的调用)给出的行没有任何缺失值。

请尝试使用data.table版本:

library(data.table)
setDT(df)
names(df)[df[,sapply(.SD, function(x) any(is.na(x))),]]
[1] "b" "c"
使用@akrun代码的微基准标记:

set.seed(49)
df1 <- as.data.frame(matrix(sample(c(NA,1:200), 1e4*5000, replace=TRUE), ncol=5000))
setDT(df1)


f1 <- function() {contains_any_na = sapply(df1, function(x) any(is.na(x)))
           names(df1)[contains_any_na]}

f2 <- function() {colnames(df1)[!complete.cases(t(df1))] }
f3 <- function() { names(df1)[!!colSums(is.na(df1))] }

f4 <- function() { names(df1)[df1[,sapply(.SD, function(x) any(is.na(x))),]] }

microbenchmark(f1(), f2(), f3(), f4(), unit="relative")   
# Unit: relative
#  expr       min        lq    median       uq      max neval
#  f1()  1.000000  1.000000  1.000000 1.000000 1.000000   100
#  f2() 10.459124 10.928821 10.955986 9.858967 7.069066   100
#  f3()  3.323144  3.805183  4.159624 3.775549 2.797329   100
#  f4() 10.108998 10.242207 10.121022 9.117067 6.576976   100
set.seed(49)

df1对于这一点,一个简单的一行是:

colnames(df[,sapply(df, function(x) any(is.na(x)))])
说明:

sapply(df, function(x) any(is.na(x)))

对于至少为1 NA的列,返回True/False
df[,sapply(df,函数(x)any(is.na(x)))]
获取数据帧的子集,该子集的所有列至少为1 na。而
colnames
给出了这些列的名称。

您能否提供一些更详细的说明,说明您的解决方案的工作原理,例如,取一个逻辑向量的和得到的真值的数量,
表示
不是
。这将使答案对OP和其他人更有用。@Paul Hiemstra感谢您的评论。我添加了一些解释。谢谢,但是为什么我不能使用名称(colSums(is.na(df))>0)?但是我得到:>names(colSums(is.na(df))>0)[1]“a”“b”“c”你的两个解决方案比较慢,因为
t(df)
is.na(df)
创建矩阵。这将是最慢的解决方案:)@rnso我只是开玩笑,我的评论只是说,并不是因为您使用data.table,您将获得最快的解决方案+1用于您和akrun的基准测试。此处花费的时间是由于
.SD
df1
的深度副本。这可以通过
避免,以提高操作速度,而无需
。请参阅。@Arun当然。。请参阅akrun答案中的我的编辑(性能说明)。@Arun因为性能是由akrun完成的,而我的回答是以“acrobatic solution”开始的,OP接受了它,我不知道为什么(声誉是):),但请随意编辑它!
library(data.table)
setDT(df)
names(df)[df[,sapply(.SD, function(x) any(is.na(x))),]]
[1] "b" "c"
set.seed(49)
df1 <- as.data.frame(matrix(sample(c(NA,1:200), 1e4*5000, replace=TRUE), ncol=5000))
setDT(df1)


f1 <- function() {contains_any_na = sapply(df1, function(x) any(is.na(x)))
           names(df1)[contains_any_na]}

f2 <- function() {colnames(df1)[!complete.cases(t(df1))] }
f3 <- function() { names(df1)[!!colSums(is.na(df1))] }

f4 <- function() { names(df1)[df1[,sapply(.SD, function(x) any(is.na(x))),]] }

microbenchmark(f1(), f2(), f3(), f4(), unit="relative")   
# Unit: relative
#  expr       min        lq    median       uq      max neval
#  f1()  1.000000  1.000000  1.000000 1.000000 1.000000   100
#  f2() 10.459124 10.928821 10.955986 9.858967 7.069066   100
#  f3()  3.323144  3.805183  4.159624 3.775549 2.797329   100
#  f4() 10.108998 10.242207 10.121022 9.117067 6.576976   100
colnames(df[,sapply(df, function(x) any(is.na(x)))])
sapply(df, function(x) any(is.na(x)))