聚合数据集

Aggregating a dataset

我有一个按以下方式列出的刑事犯罪历史数据集:

ID Charge  Chargedate VictimID ...
1  Robbery 2013-04-05  1  
1  Theft   2013-04-06  2 
1  Theft   2013-04-07  2
2  Homicide2013-04-08  3
2  Theft   2013-04-09  3
2  Burglary2013-04-10  3
...

我想以两种方式重塑数据集。 首先,我想重塑,使每一行对应一个唯一的 ID 值,没有 victimID。我还想通过计数来总结指控的存在。例如我不想在数据集中有 15 个盗窃变量,我只想有一个值为 15 的盗窃计数变量。

例如

ID Robberycount Robberydate1 Theftcount Theftdate1 Theftdate2 ...
1  1             2013-04-05  2          2013-04-06 2013-04-07
2  0             NA          1          2013-04-09 NA      
...

我想创建的另一个数据集涉及重塑数据集,但让每一行对应于每个唯一的 ID 和 victimID 对,例如

ID VictimID Robberycount Robberydate1 Theftcount Theftdate1 Theftdate2 ...
1  1        1             2013-04-05  0          NA         NA
1  2        0             NA          2          2013-04-06 2013-04-07
2  3        0             NA          1          2013-04-09 NA
...

我已经尝试使用包 Melt 来执行此操作,但我似乎无法获得我想要的结果。特别是,我不知道如何使用诸如 dcast 或 melt 之类的函数聚合犯罪数据,并为每项指控制定特定的日期。有没有一种方法可以在不诉诸手动排序数据集的情况下实现我想要的?

您需要分两步完成此操作,因此将两次变宽。因此,您必须先准备两把钥匙。丑陋的事情是你最终有更多的行,可以用 dplyr::summariseunique 修复(na.rm 在这里 unique 中是个不错的功能;-)) .试试这个:

df <- read.table(text = "ID Charge  Chargedate VictimID
                 1  Robbery 2013-04-05  1  
                 1  Theft   2013-04-06  2 
                 1  Theft   2013-04-07  2
                 2  Homicide 2013-04-08  3
                 2  Theft   2013-04-09  3
                 2  Burglary 2013-04-10  3
                 ", header = TRUE, stringsAsFactors = FALSE)

library(dplyr)
library(tidyr)
# first data frame:
df %>%
  group_by(ID, Charge) %>% 
  mutate(key_date = paste0(Charge, "date", seq_len(n())),
         key_count = paste0(Charge, "count"),
         count = n()) %>% 
  ungroup() %>% 
  select(-Charge, -VictimID) %>% 
  spread(key = key_count, value = count, fill = 0) %>% 
  spread(key = key_date, value = Chargedate) %>% 
  group_by(ID) %>% 
  mutate_at(.vars = vars(matches("count$")), sum) %>% 
  summarise_all(.funs = function(x) {
    x <- unique(x[!is.na(x)])
    ifelse(length(x) == 0, NA_character_, x)
  })

# second data frame you asked for:
df %>%
  group_by(ID, Charge, VictimID) %>% 
  mutate(key_date = paste0(Charge, "date", seq_len(n())),
         key_count = paste0(Charge, "count"),
         count = n()) %>% 
  ungroup() %>% 
  select(-Charge) %>% 
  spread(key = key_count, value = count, fill = 0) %>% 
  spread(key = key_date, value = Chargedate) %>% 
  group_by(ID, VictimID) %>% 
  mutate_at(.vars = vars(matches("count$")), sum) %>% 
  summarise_all(.funs = function(x) {
    x <- unique(x[!is.na(x)])
    ifelse(length(x) == 0, NA_character_, x)
  })