Как подсчитать количество строк в data.table, используя одно и то же условие для нескольких столбцов в R - PullRequest
1 голос
/ 12 июля 2020

Если у меня есть таблица данных ниже в R

dt <- data.table(x = c("No", "No", "Yes")
              ,  y = c("No", "Yes", "Yes")
              ,  z = c("No", "No", "No")
              ,  q = c("Hi", "Where, "When")
              ,  AA = c(1, 1,1)
              ,  ID = c(999, 789, 567)
              , bop = c(2345, 2222,2222))

и я хочу получить количество «Нет» в каждой переменной (x, y, z) ниже формат

Variable Type Count

 x     No      2

 y     No     1

 z     No     3

Я не могу передать тот же фильтр в нужные столбцы. Я могу передать фильтр только в один столбец

dt[, .(.N), by = .(x,y,z)]


1 Ответ

2 голосов
/ 12 июля 2020

Мы можем использовать melt для преобразования в «длинный» формат, а затем выполнить группировку по «переменной» (т.е. столбцу с именем столбца), получить число «Нет», sum сопоставив логический вектор ( value == 'No')

library(data.table)
melt(dt, id.var = 'q')[, .(Type = 'No', Count = sum(value == 'No')), .(variable)]
#   variable Type Count
#1:        x   No     2
#2:        y   No     1
#3:        z   No     3

Для нового примера

melt(dt[, .(x, y, z)], measure = c('x', 'y', 'z'))[, 
   .(Type = 'No', Count = sum(value == 'No')), .(variable)]
#    variable Type Count
#1:        x   No     2
#2:        y   No     1
#3:        z   No     3

Или укажите логическое условие в i и используйте .N

melt(dt[, .(x, y, z)], measure = c('x', 'y', 'z'))[value == 'No',
       .(Type = first(value), Count = .N), variable]
#   variable Type Count
#1:        x   No     2
#2:        y   No     1
#3:        z   No     3

Или без melt ing мы можем l oop поверх Subset of Data.table (.SD), создать логический вектор и уменьшить list до одного вектора с Reduce

dt[, .(variable = names(.SD), Type = 'No', 
     Count = Reduce(`+`, lapply(.SD, `==`, 'No'))), .SDcols = x:z]
#  variable Type Count
#1:        x   No     3
#2:        y   No     2
#3:        z   No     1

Или используя rowSums

dt[, .(Variable = names(.SD), Type = 'No',
        Count = rowSums(.SD == 'No')), .SDcols = x:z]

В коде OP столбцы группировки были взяты как 'x', 'y', 'z'. Затем, если мы сделаем .N, он ищет количество строк для каждого уникального набора значений в этих столбцах, и это будет 1 для каждого случая, потому что есть только 1 строка для No No No, No Yes No или Yes Yes No

...