Выбор или подмножество переменных, чьи суммы столбцов не равны нулю - PullRequest
0 голосов
/ 31 октября 2018

Я хочу выбрать или установить подмножество переменных во фрейме данных, чья сумма столбцов не равна нулю, но также , сохраняя и другие факторные переменные . Это должно быть довольно просто, но я не могу понять, как запустить функцию 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

Затем я попытался выбрать только 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

Я мог бы просто сделать cbind(A = df$A, df2), но так как у меня есть набор данных с 3000 строками и 200 столбцами, я боюсь, что это может привести к ошибкам (если значения сортируются, например, по-разному).

Попытка подмножества переменных B, C, D в функции sum() также не работает:

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

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Попробуйте это:

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

Обоснованием является то, что для ||, если левая сторона равна TRUE, правая сторона не будет оцениваться.

Примечание:

  • вторым аргументом для select_if должно быть имя функции или формула (лямбда-функция). ~ необходимо сказать 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]
0 голосов
/ 31 октября 2018

Это решение с использованием data.table

df<-data.table(
  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)
)

df2<-df[,lapply(X = .SD,FUN = function(x){sum(as.numeric(x))}),.SDcols = colnames(df)]
df[,which(is.na(df[1,]) == F),with = F]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...