Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.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
从所有值均为NA的dataframe中删除列_R_Apply_Dataframe - Fatal编程技术网

从所有值均为NA的dataframe中删除列

从所有值均为NA的dataframe中删除列,r,apply,dataframe,R,Apply,Dataframe,我的数据帧有问题,自己无法真正解决该问题: 数据帧具有任意列属性,每行代表一个数据集。 问题是: 如何删除所有行的值均为NA的列?尝试以下操作: df <- df[,colSums(is.na(df))<nrow(df)] df另一种方法是使用apply()函数 如果你有data.frame df <- data.frame (var1 = c(1:7,NA), var2 = c(1,2,1,3,4,NA,NA,9),

我的数据帧有问题,自己无法真正解决该问题:
数据帧具有任意列属性,每行代表一个数据集。 问题是:
如何删除所有行的值均为NA的列?

尝试以下操作:

df <- df[,colSums(is.na(df))<nrow(df)]

df另一种方法是使用
apply()
函数

如果你有data.frame

df <- data.frame (var1 = c(1:7,NA),
                  var2 = c(1,2,1,3,4,NA,NA,9),
                  var3 = c(NA)
                  )

迄今为止提供的两种方法都无法处理大型数据集,因为(除其他内存问题外)它们创建了
is.na(df)
,这将是一个与
df
大小相同的对象

这里有两种更节省内存和时间的方法

使用
过滤器的方法

Filter(function(x)!all(is.na(x)), df)
以及使用data.table的方法(用于一般时间和内存效率)

库(data.table)

DT我希望这也能有所帮助。它可以做成一个命令,但我发现把它分成两个命令更容易阅读。我按照下面的指令做了一个函数,并且工作得非常快

naColsRemoval=函数(数据表){
na.cols=DataTable[,(其中(应用(is.na(.SD),2,all))]
DataTable[,unlist(na.cols):=NULL,带=F]
}

.SD将允许将验证限制在表的一部分,如果您愿意的话,但它会将整个表作为

df[sapply(df,function(x)all(is.na(x))]Update
df[sapply(df, function(x) all(is.na(x)))] <- NULL
现在,您可以使用
where
selection助手使用
select
<如果取代了
,但从dplyr 1.0.2起仍能正常工作,则代码>选择_。(感谢@mcstrother引起注意)


游戏延迟,但您也可以使用
看门人
软件包。此函数将删除所有为NA的列,并且可以更改为删除所有为NA的行


df另一个带有
purrr
package的选项:

library(dplyr)

df <- data.frame(a = NA,
                 b = seq(1:5), 
                 c = c(rep(1, 4), NA))

df %>% purrr::discard(~all(is.na(.)))
df %>% purrr::keep(~!all(is.na(.)))
库(dplyr)
df%purrr::丢弃(~all(is.na)())
df%>%purrr::keep(~!all(is.na())

一个方便的
基本R
选项可以是
colMeans()


您可以使用门卫软件包
remove\u empty

library(janitor)

df %>%
  remove_empty(c("rows", "cols")) #select either row or cols or both
另外,还有另一种dplyr方法

 library(dplyr) 
 df %>% select_if(~all(!is.na(.)))

如果您只想排除/保留具有一定数量缺失值的列,例如

 df %>% select_if(colSums(!is.na(.))>500)

根据我在应用之前的答案时遇到的困难,我发现我需要修改他们的方法,以实现这里的问题:

如何去掉所有行的值均为NA的列?

首先请注意,我的解决方案只有在没有重复列的情况下才有效(这个问题已经解决了)

其次,它使用
dplyr

而不是

df <- df %>% select_if(~all(!is.na(.)))
df%select_if(~all(!is.na())
我发现有效的是

df <- df %>% select_if(~!all(is.na(.)))
df%select\u如果(~!all(is.na)())
关键是“not”符号“!”需要位于通用量词的外部。例如,如果
操作符作用于列,则
选择\u。在这种情况下,它只选择那些不符合条件的

每个元素都等于“NA”


看门人::remove_constant()做得很好。

我希望这会更快,因为colSum()解决方案似乎做了更多的工作。但是在我的测试集上(之前1614个变量中有213个obs,而之后有1377个变量),它需要的时间正好是原来的3倍。(但有趣的方法是+1。)非常好。您可以对
数据.frame
执行相同的操作。这里没有真正需要
数据.table
。关键是
lappy
,它避免了
is.na(df)复制整个对象
+10指出这一点。你会如何使用data.frame?@matt-dowle@s_a,
bd1@mnel我想你需要在
函数(x)
之后删除
-谢谢你的示例btwCan,你可以用:=或set()更快地完成它?这会创建一个与旧对象大小相同的对象,这是大型对象上的内存问题。最好使用一个函数来减小大小。下面的答案是使用筛选器或使用data.table将有助于您的内存使用。这似乎不适用于非数字列。如果列重复,它会更改列名以对非数字列执行此操作ic列,@mnel使用过滤器()的解决方案这是一个很好的方法。在这里可以找到多种方法的基准来寻找
dplyr
解决方案。我没有失望。谢谢!我发现这有一个问题,即如果在dplyr中现在取代了
temp%>%se,它也会删除大多数但并非所有值都缺失的变量
select\u,那么最后两行将是
temp%>%se选择(where(not_all_na))
在最新语法中——尽管从dplyr 1.0.2开始,如果
select\u仍然有效,也可以
temp%>%select(where(~!all(is.na(.x)))
如果您不想在单独的一行中定义函数,则可以使用。@mcstrother谢谢-这是对我的答案的一个非常有用的更新。如果您想自己回答,我将很乐意回滚编辑。
df[, colMeans(is.na(df)) != 1]
library(janitor)

df %>%
  remove_empty(c("rows", "cols")) #select either row or cols or both
 library(dplyr) 
 df %>% select_if(~all(!is.na(.)))
df %>% select_if(colSums(!is.na(.)) == nrow(df))
 df %>% select_if(colSums(!is.na(.))>500)
df <- df %>% select_if(~all(!is.na(.)))
df <- df %>% select_if(~!all(is.na(.)))