R, Дополнение по агрегированию data.table
Можно ли агрегировать с дополнением в R data.tables. Пример ниже.
library(data.table)
dt <- data.table(a=c("word1","word2","word2","word2"), b=c("cat1","cat1","cat1","cat2"))
Чтобы получить количество конкретных слов в категории
newdt <- dt[,(.N),by=.(a,b)]
#word1,cat1 - 1
#word2,cat1 - 2
#word2,cat2 - 1
Как я могу посчитать количество всех других слов в категории? Или, соответственно, количество других категорий, в которых находится это слово? Что-то вроде следующего?
#doesn't work
#newdt2 <- dt[a!=a,(.N),by=.(a,b)]
#the expected answer would be
#word1,cat1 - 2
#word2,cat1 - 1
#word2,cat2 - 0
Я не могу найти никакой помощи по этому вопросу в онлайн-учебниках или вопросах. Есть ли простой способ получить дополнение. Решение Data.table было бы хорошо, так как работа с таблицей строк 50M. Спасибо!
2 ответа
Следуя идее Бруно, вычислить разницу общего количества по категориям за вычетом количества слов в каждой категории, но используя data.table
Синтаксис с обновлением при соединении становится "однострочным":
library(data.table)
dt <-data.table(a = c("word1", rep("word2", 3L)), b = c(rep("cat1", 3L), "cat2"))
dt[, .N, by = .(a, b)][dt[, .N, by = b], on = "b", Nc := i.N - N][]
a b N Nc 1: word1 cat1 1 2 2: word2 cat1 2 1 3: word2 cat2 1 0
Ниже приведен ваш код (я добавил двойные кавычки, чтобы он работал):
library(data.table)
dt <-
data.table(a=c("word1","word2","word2","word2"),b=c("cat1","cat1","cat1","cat2"))
newdt <- dt[,(.N),by=.(a,b)]
names(newdt) = c("a", "b", "cnt") # rename the count column
Следующая строка подсчитывает, сколько раз появляется каждая категория
catCnt = dt[,(.N),by=.(b)]
names(catCnt) = c("b", "tot_b")
catCnt
Количество слов, принадлежащих каждой категории, кроме текущего слова, представляет собой разницу между количеством слов, принадлежащих к категории, и количеством раз, которое пара (category
, word
) появляется. Чтобы достичь результата, я объединяю два data.table
объекты по столбцу категории
aux = merge(newdt, catCnt, by="b")
а затем я вычисляю разницу между общим количеством и количеством "пар":
aux$cnt_not_a = aux$tot_b - aux$cnt
Если вы хотите сохранить только необходимый столбец:
res = aux[, c("b", "a", "cnt_not_a")]
res
Я не знаю, если вы можете достичь этого с помощью data.table
только команды, но это выглядит довольно просто для меня...