我想从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 ) ]
答案 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
只出现了TRUE
或sd!=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")