删除标准差为零的列

时间:2015-06-12 08:04:58

标签: r dataframe

我想从data.frame中删除标准差为零的所有列。

这不起作用:

  df <- df[, ! apply(df , 2 , function(x) sd(x)==0 ) ]

我收到错误:

  

选择了未定义的列

更新

我选择Filter作为我的首选答案,因为它似乎也处理了NA,这非常有用。

例如,在

df <- data.frame(v1=c(0,0,NA,0,0), v2=1:5)

专栏&#39; v1&#39;在Filter方法产生错误时,apply会移除。

感谢所有其他解决方案,我从中学到了很多东西。

UPDATE2:

应用给出的那些错误可以通过将na.rm = TRUE添加到对sd的调用来修复,如下所示:

df[, ! apply(df , 2 , function(x) sd(x, na.rm = TRUE)==0 ) ]

3 个答案:

答案 0 :(得分:6)

使用过滤器:

Filter(function(x) sd(x) != 0, df)

答案 1 :(得分:5)

除了使用Filter的@grrgrrbla和@akrun的回答之外,这里有正确的方法来做你最初的想法:

df <- df[, !sapply(df, function(x) { sd(x) == 0} )]

df <- df[, sapply(df, function(x) { sd(x) != 0} )]

我使用sapply()得到一个向量,当数据帧列的标准偏差为0时为TRUE,否则为FALSE。然后我使用这个向量对原始数据框进行子集化。

答案 2 :(得分:3)

您可以在没有匿名函数调用的情况下使用Filter,因为'0'的'SD'被强制为'FALSE'而其他所有内容都被'TRUE'强制为Filter只出现了TRUEsd!=0

 Filter(sd, df)

或者,如果列中包含混合类,length(unique)可能更为通用。

 df[vapply(df, function(x) length(unique(na.omit(x)))>1, logical(1L))]

或者我们可以使用tidyverse

library(tidyverse)
library(magrittr)
df %>% 
   map_lgl(~sd(.) !=0) %>%
   extract(df, .)  

数据

 df <- structure(list(V1 = c(1, 4, 2, 5), V2 = c(2, 2, 2, 2), V3 = c(3, 
  4, 3, 3), V4 = c(1, 2, 3, 3)), .Names = c("V1", "V2", "V3", "V4"
  ), row.names = c(NA, -4L), class = "data.frame")