计算更改时filter和group_by之间的差异

时间:2018-02-08 14:54:42

标签: r dplyr

我试图计算百分比变化,但我不明白为什么会出现这种错误:

Column 'change' must be length 1 (the group size), not 0

这是一个example数据框:

structure(list(Kennisnamedatum = structure(c(16436, 16436, 16441, 
17167, 17167, 17169), class = "Date"), weekdag = structure(c(4L, 
4L, 2L, 7L, 7L, 2L), .Label = c("Mon", "Tue", "Wed", "Thu", "Fri", 
"Sat", "Sun"), class = "factor"), jaar = c(2015L, 2015L, 2015L, 
2017L, 2017L, 2017L), Gemeente = c("Amsterdam", "Rotterdam", 
"S-Gravenhage", "Amsterdam", "S-Gravenhage", "Rotterdam"), Plaats = c("Amsterdam", 
"Rotterdam", "S-Gravenhage", "Amsterdam", "S-Gravenhage", "Rotterdam"
), Beleidscode = c("Bezit harddrugs", "Bezit harddrugs", "Bezit harddrugs", 
"Bezit harddrugs", "Bezit harddrugs", "Bezit harddrugs"), aantal_misdrijven = c(16L, 
1L, 1L, 10L, 1L, 1L), misdrijven_per_jaar = c(829L, 368L, 205L, 
649L, 197L, 349L)), class = c("grouped_df", "tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -6L), vars = c("jaar", "Gemeente", 
"Beleidscode"), drop = TRUE, .Names = c("Kennisnamedatum", "weekdag", 
"jaar", "Gemeente", "Plaats", "Beleidscode", "aantal_misdrijven", 
"misdrijven_per_jaar"), indices = list(0L, 1L, 2L, 3L, 5L, 4L), group_sizes = c(1L, 
1L, 1L, 1L, 1L, 1L), biggest_group_size = 1L, labels = structure(list(
    jaar = c(2015L, 2015L, 2015L, 2017L, 2017L, 2017L), Gemeente = c("Amsterdam", 
    "Rotterdam", "S-Gravenhage", "Amsterdam", "Rotterdam", "S-Gravenhage"
    ), Beleidscode = c("Bezit harddrugs", "Bezit harddrugs", 
    "Bezit harddrugs", "Bezit harddrugs", "Bezit harddrugs", 
    "Bezit harddrugs")), class = "data.frame", row.names = c(NA, 
-6L), vars = c("jaar", "Gemeente", "Beleidscode"), drop = TRUE, .Names = c("jaar", 
"Gemeente", "Beleidscode")))

当我在城市(gemeente),Fellonies(Beleidscode)上过滤数据框并离开两年(jaar)时,我想计算它的工作变化。但我不想过滤,而是按照wob_dfgemeente计算所有(df:Beleidscodejaargroup_by本来是显而易见的选择,但这不起作用。我无法绕过这个......

有效的代码(原始wob_df,要分享的数据框太大):

library(dplyr)

wob_df %>%
  distinct(Gemeente, .keep_all = T) %>%
  filter(Gemeente %in% c("Amsterdam", "Rotterdam", "S-Gravenhage"),
         Beleidscode == "Bezit harddrugs",
         jaar != 2016) %>%
  group_by(Gemeente) %>%
  mutate(change = (misdrijven_per_jaar[jaar == 2017] - misdrijven_per_jaar[jaar == 2015]) / misdrijven_per_jaar[jaar == 2015])

相同的任务,但没有过滤器:

wob_df %>%
  group_by(Gemeente, Beleidscode, jaar) %>%
  mutate(change = (misdrijven_per_jaar[jaar == 2017] - misdrijven_per_jaar[jaar == 2015]) / misdrijven_per_jaar[jaar == 2015])

这会出现以下错误:

`Column 'change' must be length 1 (the group size), not 0`

2 个答案:

答案 0 :(得分:1)

假设您已经清理了数据,每个Gemeente和Beleidscode都有一个misdrijven_per_jaar(因此您可以进行一对一的更改),重塑数据会使这更加简单。这就是tidyr的用途。我将通过tidyverse

加载它
library(tidyverse)
mydf %>% 
    select(Gemeente, Beleidscode, jaar, misdrijven_per_jaar) %>% 
    group_by(Gemeente, Beleidscode) %>% 
    spread(jaar, misdrijven_per_jaar) %>% 
    mutate(difference = `2017` - `2015`)

给出了

# A tibble: 3 x 5
# Groups:   Gemeente, Beleidscode [3]
  Gemeente     Beleidscode     `2015` `2017` difference
  <chr>        <chr>            <int>  <int>      <int>
1 Amsterdam    Bezit harddrugs    829    649       -180
2 Rotterdam    Bezit harddrugs    368    349       - 19
3 S-Gravenhage Bezit harddrugs    205    197       -  8

您可以随意播放曲调以计算相对变化等。

答案 1 :(得分:0)

如果你想在几年内制定条件,你不必按年分组。

df %>%
  group_by(Gemeente, Beleidscode) %>%
  mutate(change = (misdrijven_per_jaar[jaar == 2017] - misdrijven_per_jaar[jaar == 2015]) / misdrijven_per_jaar[jaar == 2015])