首页 > 解决方案 > 创建只有 1 个 ID 列的宽数据

问题描述

我有一个看起来像这样的数据框:

  ID Code_Type Code date 
   1   10        4    1
   1    9        5    2
   2    10       6    3
   2    9        7    4

我希望它看起来像这样:

  ID date.1 date.2  9  10
   1   1        2   5  4
   2   3        4   7  6

不同的日期在同一行上有不同的列。

我目前的代码是这样的:

#Example df
df <- data.frame("ID" = c(1,1,2,2), 
                 "Code_Type" = c(10,9,10,9), 
                 "Code" = c(4,5,6,7),
                 "date"= c(1,2,3,4))

spread(df, Code_Type,Code)

这输出:

  ID date   9  10
   1   1    NA  4
   1   2    5  NA
   2   3    NA  6
   2   4    7  NA

这与我想要的类似我只是不知道如何使日期列变成多列。任何帮助或额外阅读表示赞赏。

为了澄清这是我预期的输出数据框

  ID date.1 date.2  9  10
   1   1        2   5  4
   2   3        4   7  6

标签: rtidyrreshape2

解决方案


这是一个dplyr/tidyr替代方案:

df %>% mutate(date.1 = date %% 2 * date) %>% mutate(date.2 = - (date %% 2 - 1) * date) %>% select(-date) %>% spread(Code_Type, Code) %>% group_by(ID) %>% summarise_all(list(~ sum(.[!is.na(.)])))

# A tibble: 2 x 5
     ID date.1 date.2   `9`  `10`
  <dbl>  <dbl>  <dbl> <dbl> <dbl>
1     1      1      2     5     4
2     2      3      4     7     6

这个想法是将date列分成两列,无论date偶数还是奇数。这是使用模 ( %%) 运算符(以及一些额外的数字运算)完成的。date.1 = date %% 2 * date捕获日期中的奇数并且0适用于所有其他人;date.2 = - (date %% 2 - 1) * date抓住偶数并0适用于所有其他人。

之后就很简单了:选择除date;之外的所有列 将其扩展为宽格式,再次有点棘手,总结ID并删除所有NAs ( group_by(ID) %>% summarise_all(list(~ sum(.[!is.na(.)]))).


推荐阅读