选择或子集列总和不为零的变量

Ste*_*fan 4 r dplyr

我想在列总和不为零的数据帧中选择或子集变量,但也要保留其他因子变量.它应该相当简单,但我无法弄清楚如何select_if()使用dplyr以下方法对变量子集运行该函数:

df <- data.frame(
  A = c("a", "a", "b", "c", "c", "d"),
  B = c(0, 0, 0, 0, 0, 0),
  C = c(3, 0, 0, 1, 1, 2),
  D = c(0, 3, 2, 1, 4, 5)
)

require(dplyr)
df %>% 
  select_if(funs(sum(.) > 0))

#Error in Summary.factor(c(1L, 1L, 2L, 3L, 3L, 4L), na.rm = FALSE) : 
#  ‘sum’ not meaningful for factors
Run Code Online (Sandbox Code Playgroud)

然后我尝试只选择B, C, D,这有效,但我不会有变量A:

df %>% 
  select(-A) %>% 
  select_if(funs(sum(.) > 0)) -> df2
df2
#  C D
#1 3 0
#2 0 3
#3 0 2
#4 1 1
#5 1 4
#6 2 5
Run Code Online (Sandbox Code Playgroud)

我可以这样做,cbind(A = df$A, df2)但由于我有一个包含3000行和200列的数据集,我担心这可能会引入错误(例如,如果值排序不同).

尝试B, C, Dsum()函数中使用子集变量也不起作用:

df %>% 
  select_if(funs(sum(names(.[2:4])) > 0))
#data frame with 0 columns and 6 rows
Run Code Online (Sandbox Code Playgroud)

mt1*_*022 8

试试这个:

df %>% select_if(~ !is.numeric(.) || sum(.) != 0)
#   A C D
# 1 a 3 0
# 2 a 0 3
# 3 b 0 2
# 4 c 1 1
# 5 c 1 4
# 6 d 2 5
Run Code Online (Sandbox Code Playgroud)

理由是,||如果左侧是TRUE,则不会评估右侧.

注意:

  • 第二个参数select_if应该是函数名或公式(lambda函数).将~要告诉select_if!is.numeric(.) || sum(.) != 0应转换为一个功能.
  • 正如下面由@ zx8754评论的那样,is.factor(.)如果只想保留factor列,则应该使用它.

编辑:基础R解决方案

cols <- c('B', 'C', 'D')
cols.to.keep <- cols[colSums(df[cols]) != 0]
df[!names(df) %in% cols || names(df) %in% cols.to.keep]
Run Code Online (Sandbox Code Playgroud)