Dplyr: помещать отсчеты в новую переменную
Хотелось бы получить руку на dplyr-код, но не могу понять это. Вы видели аналогичную проблему, описанную здесь для многих переменных (подведение итогов с коэффициентом с dplyr и Ввод числа учетных значений значений в новые переменные, как это сделать в R с dplyr?), однако моя задача несколько меньше.
Учитывая кадр данных, как мне подсчитать частоту переменной и поместить ее в новую переменную.
set.seed(9)
df <- data.frame(
group=c(rep(1,5), rep(2,5)),
var1=round(runif(10,1,3),0))
Тогда имеем:
>df
group var1
1 1 1
2 1 1
3 1 1
4 1 1
5 1 2
6 2 1
7 2 2
8 2 2
9 2 2
10 2 3
Хотелось бы, чтобы третий столбец указывал per-group (group
), сколько раз var1
, в этом примере это будет: count = (4,4,4,4,1,1,3,3, 3,1).
Я пробовал - без успеха - вещи вроде:
df %>% group_by(group) %>% rowwise() %>% do(count = nrow(.$var1))
Пояснения очень оценены!
Ответы
Ответ 1
Все, что вам нужно сделать, это группировать ваши данные по обоим столбцам, "группа" и "var1":
df %>% group_by(group, var1) %>% mutate(count = n())
#Source: local data frame [10 x 3]
#Groups: group, var1
#
# group var1 count
#1 1 1 4
#2 1 1 4
#3 1 1 4
#4 1 1 4
#5 1 2 1
#6 2 1 1
#7 2 2 3
#8 2 2 3
#9 2 2 3
#10 2 3 1
Редактировать после комментария
Вот пример того, как вы НЕ ДОЛЖНЫ СДЕЛАТЬ ЭТО:
df %>% group_by(group, var1) %>% do(data.frame(., count = length(.$group)))
Реализация dplyr с n()
, безусловно, намного быстрее, чище и короче и всегда должна быть предпочтительнее таких реализаций, как указано выше.
Ответ 2
Мы можем использовать, возможно, еще одну удобную функцию tally
из dplyr
df %>% group_by(group, var1) %>% tally()
# Source: local data frame [5 x 3]
# Groups: group
#
# group var1 n
# 1 1 1 4
# 2 1 2 1
# 3 2 1 1
# 4 2 2 3
# 5 2 3 1
Ответ 3
Две альтернативы:
1: с базой R:
# option 1:
df$count <- ave(df$var1, df$var1, df$group, FUN = length)
# option 2:
df <- transform(df, count = ave(var1, var1, group, FUN = length))
который дает:
> df
group var1 count
1 1 1 4
2 1 1 4
3 1 1 4
4 1 1 4
5 1 2 1
6 2 1 1
7 2 2 3
8 2 2 3
9 2 2 3
10 2 3 1
2: с data.table:
library(data.table)
setDT(df)[, count:=.N, by = .(group, var1)]
который дает тот же результат:
> df
group var1 count
1: 1 1 4
2: 1 1 4
3: 1 1 4
4: 1 1 4
5: 1 2 1
6: 2 1 1
7: 2 2 3
8: 2 2 3
9: 2 2 3
10: 2 3 1
Если вы хотите обобщить, вы можете использовать:
# with base R:
aggregate(id ~ group + var1, transform(df, id = 1), length)
# with 'dplyr':
count(df, group, var1)
# with 'data.table':
setDT(df)[, .N, by = .(group, var1)]
Ответ 4
Возможно, это новая функциональность, но это можно сделать с помощью одной команды dplyr
:
df %>% add_count(group, var1)
group var1 n
1 1 1 4
2 1 1 4
3 1 1 4
4 1 1 4
5 1 2 1
6 2 1 1
7 2 2 3
8 2 2 3
9 2 2 3
10 2 3 1