Накопительная сумма по 2 критериям в R - PullRequest
0 голосов
/ 13 марта 2019

У меня есть база данных, в которой я хочу вычислить совокупную сумму по 2 критериям

dfdata = data.frame(car = c("toyota","toyota","toyota","toyota","toyota",
                            "honda","honda","honda","honda",
                            "lada","lada","lada","lada"),
                    year = c(2000,2000,2001,2001,2002,2001,2001,2002,2002,2003,2004,2005,2006),
                    id = c("a","b","a","c","a","d","d","d","e","f","f","f","f"))

Вы можете просмотреть данные:

dfdata
      car year id
1  toyota 2000  a
2  toyota 2000  b
3  toyota 2001  a
4  toyota 2001  c
5  toyota 2002  a
6   honda 2001  d
7   honda 2001  d
8   honda 2002  d
9   honda 2002  e
10   lada 2003  f
11   lada 2004  f
12   lada 2005  f
13   lada 2006  f

Представьте, что я наблюдал проезжающие мимо автомобилии что табличка на нем является «удостоверением личности».Таким образом, машина с таким же идентификатором - это точно такая же машина.

  1. Мне нужна сумма автомобилей, которые я видел за один год
  2. Мне нужна совокупная сумма автомобилей, которые я видел за года
  3. Я хочу, чтобы совокупная сумма автомобилей компаний, которые я видел более одного раза (считая те, которые я видел в том же году и в другие годы, И еще одна колонка, подсчитывающая те,что я видел ТОЛЬКО в другие годы)

Вот как я получил пункт 1. и пункт 2.

dfdata %>%  
  group_by(car, year) %>% 
  dplyr::summarise(nb = n())  %>% 
  dplyr::mutate(cs = cumsum(nb)) %>% 
  ungroup()

nb - это количество автомобилей из определенногопроизводителя я видел в конкретном году.cs - совокупная сумма автомобилей по годам.

# A tibble: 9 x 4
  car     year    nb    cs
  <fct>  <dbl> <int> <int>
1 honda   2001     2     2
2 honda   2002     2     4
3 lada    2003     1     1
4 lada    2004     1     2
5 lada    2005     1     3
6 lada    2006     1     4
7 toyota  2000     2     2
8 toyota  2001     2     4
9 toyota  2002     1     5

Но обратите внимание, что я потерял столбец идентификатора.Как узнать количество автомобилей, которые я видел несколько раз для одного и того же идентификатора.

Окончательный результат должен основываться на идентификаторе группировки (для ответа на пункт 3):

     car year nb cs curetrap curetrap.no.same.year
1  honda 2001  2  2        1                     0
2  honda 2002  2  4        2                     1
3   lada 2003  1  1        0                     0
4   lada 2004  1  2        1                     1
5   lada 2005  1  3        2                     2
6   lada 2006  1  4        3                     3
7 toyota 2000  2  2        0                     0
8 toyota 2001  2  4        1                     1
9 toyota 2002  1  5        2                     2

Это потому, что «Хонда» была замечена 2 раза в 2001 году и 2 раза в 2002 году. Таким образом, совокупная сумма равна 2 в 2001 году и 2 + 2 в 2002 году. Затем в том же году Я виделhonda «d» дважды, что означает, что я «повторно захватил» d «2001», и, следовательно, «1» в кюретрапе за 2001 год. В 2002 году я снова захватил honda «d», таким образом, накопленная сумма увеличилась.Для "curetrap.no.same.year" это то же самое, но я хочу игнорировать возвращение honda "d" в 2001 году, так как это тот же год.

Как это можно сделать?Так как я теряю идентификационную информацию, мне нужно сделать это в 2 шага?

Пока это то, что у меня есть:

tab.df = cbind(table(dfdata$id,dfdata$year),
      car = as.character(dfdata[match(unique(dfdata$id),table = dfdata$id),"car"]))
df.df = as.data.frame(tab.df)

  2000 2001 2002 2003 2004 2005 2006    car
a    1    1    1    0    0    0    0 toyota
b    1    0    0    0    0    0    0 toyota
c    0    1    0    0    0    0    0 toyota
d    0    2    1    0    0    0    0  honda
e    0    0    1    0    0    0    0  honda
f    0    0    0    1    1    1    1   lada

Это показывает, сколько раз я видел машину за год для определенного удостоверения личности.

1 Ответ

1 голос
/ 13 марта 2019

Вы можете разбить проблему на 2 этапа, сначала добавив двоичные переменные в исходный набор данных, которые будут помечать записи, которые вы хотите считать, а затем просто вычислив сумму и сумму этих флагов.

Следующий код дает желаемый результат

dfdata %>% 
  group_by(car, id) %>% 
  arrange(year, .by_group=TRUE) %>% 
  dplyr::mutate(already_seen = row_number()>1, already_seen_diff_year = year>year[1])  %>% 
  group_by(car, year) %>% 
  dplyr::summarise(nb = n(), cs = nb, curetrap = sum(already_seen), curetrap.no.same.year = sum(already_seen_diff_year))  %>% 
  dplyr::mutate_at(vars(cs, curetrap, curetrap.no.same.year), cumsum) %>% 
  ungroup()

Примечание: дублирующая переменная cs = nb - это просто хитрость, чтобы легко записать последующий вызов mutate_at

...