R

时间:2019-03-13 16:07:09

标签: r dataframe dplyr summarization

我有一个数据库,要在其中计算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

想象一下,我正在观察路过的汽车,并且上面的车牌是“ ID”。因此,具有相同ID的汽车就是完全相同的汽车。

  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

但是请注意,我已经失去了ID列。如何获得同一ID多次看到的汽车数量。

最终输出应基于分组ID(回答第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

这是因为“本田”在2001年出现了2次,在2002年出现了2次。因此,累计总和在2001年是2,在2002年是2 +2。然后,在同一年内我已经看过两次本田“ d”,这意味着我“夺回”了2001年的“ d”本田,因此在2001年用了“ 1”。在2002年,我再次夺回了本田“ d”,因此累计金额增加了。对于“ curetrap.no.same.year”,这是同一回事,但是由于同一年,我想忽略2001年本田“ d”的夺回。

这怎么可能呢?由于我丢失了ID信息,是否需要分两步进行?

到目前为止,这就是我所拥有的:

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

其中显示了我一年以来每次看过具有特定ID的汽车的情况。

1 个答案:

答案 0 :(得分:1)

您可以通过首先在原始数据集中添加二进制变量(将标记要计数的记录),然后简单地计算这些标记的总和来将问题分解为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的后续调用