df <- data.frame(date = as.Date(c(rep("2022-01-01", 3),
rep("2022-02-01", 3),
rep("2022-03-01", 4))),
flavor = c("Almond", "Apple", "Apricot",
"Almond", "Maple", "Mint",
"Apricot", "Pecan", "Praline", "Pumpkin"))
#> date flavor
#> 1 2022-01-01 Almond
#> 2 2022-01-01 Apple
#> 3 2022-01-01 Apricot
#> 4 2022-02-01 Almond
#> 5 2022-02-01 Maple
#> 6 2022-02-01 Mint
#> 7 2022-03-01 Apricot
#> 8 2022-03-01 Pecan
#> 9 2022-03-01 Praline
#> 10 2022-03-01 Pumpkin
Фрейм данных R выше отслеживает вкусы мороженого в магазине мороженого из месяца в месяц. В феврале были добавлены два аромата, которых не было в январе (клен, мята), и удалены два аромата (яблоко, абрикос), которые присутствовали в январе. В марте были добавлены четыре вкуса, которых не было в феврале (абрикос, пекан, пралине, тыква), и удалены три вкуса (миндаль, клен, мята), которые присутствовали в феврале.
#> date flavors.added flavors.removed
#> 1 2022-01-01 <NA> <NA>
#> 2 2022-02-01 2 2
#> 3 2022-03-01 4 3
Как написать R-скрипт для вычисления приведенного выше сводного фрейма данных? То есть мне нужен скользящий подсчет ароматов мороженого, которые были добавлены за месяц, которых не было в предыдущем месяце, а также подсчет ароматов, удаленных за месяц, которые присутствовали в предыдущем месяце.





Использование data.table:
library(data.table)
df2 = setDT(df)[, .(flavors = list(flavor)), date]
for (i in 2:nrow(df2))
set(
df2, i = i,
j = c('flavors_added', 'flavors_removed'),
list(length(setdiff(df2$flavors[[i]], df2$flavors[[i-1]])), length(setdiff(df2$flavors[[i-1]], df2$flavors[[i]])))
)
df2
# date flavors flavors_added flavors_removed
# <Date> <list> <int> <int>
# 1: 2022-01-01 Almond,Apple,Apricot NA NA
# 2: 2022-02-01 Almond,Maple,Mint 2 2
# 3: 2022-03-01 Apricot,Pecan,Praline,Pumpkin 4 3
Да, прости. Я привык, что все data.frames являются data.tables. Спасибо @Uwe за исправление.
@jophuh, проблема была вызвана тем, что df не принуждали к занятиям data.table.
В dplyr:
library(dplyr)
df %>%
group_by(date) %>%
summarise(flavors = list(flavor)) %>%
mutate(flavors.added = lengths(mapply(setdiff, flavors, lag(flavors))),
flavors.removed = lengths(mapply(setdiff, lag(flavors), flavors)))
выход
# A tibble: 3 × 4
date flavors flavors.added flavors.removed
<date> <list> <int> <int>
1 2022-01-01 <chr [3]> 3 0
2 2022-02-01 <chr [3]> 2 2
3 2022-03-01 <chr [4]> 4 3
в вашем ответе опечатка? Когда я запускаю код, я получаю
Error in drop && !has.j : invalid 'x' type in 'x && y'. Error in nrow(df2) : object 'df2' not found