求和时从长到宽重塑

Reshape from long to wide while summing

我有以下示例数据

rankP amount defaulted
   1  45925         1
   1 369550         1
   1 177975         1
   1 157850         0
   2  30400         1
   2  93950         0
   2 194075         1
   3  30975         0
   3  66775         1
   3 225850         1

并且我想转换数据,以便获得每个级别、每个默认状态 (0/1) 的数量。所需的输出如下所示:

rankP   0         1
1     157850    593450
2      93950    224475
3      30975    292625

我觉得我错过了一些非常简单的东西,到目前为止,我没有设法使用 table()aggregate()

来做到这一点

实现该目标的方法是什么?

您可以使用 dcast 将 'long' 格式重塑为 'wide' 格式。通过将 fun.aggregate 指定为 sum,我们得到 'value.var' 列的 sum。按 rankP

分组
 library(reshape2)
 dcast(df1, rankP~defaulted, value.var='amount', sum)

正如@MichaelChirico 在评论中提到的,data.table 的开发版本,即 v1.9.5 也有 dcast,这会更快。还有其他选项,例如使用多个 'value.var' 列重塑。使用当前示例,除了我们首先将 'data.frame' 转换为 'data.table' (setDT(df1)).

之外,代码将是相似的

使用 dplyrtidyr

library(dplyr)
library(tidyr)

df %>% 
  group_by(rankP, defaulted) %>% 
  summarize(amount = sum(amount)) %>% 
  spread(defaulted, amount)

#Source: local data table [3 x 3]
#Groups:

#  rankP      0      1
#1     1 157850 593450
#2     2  93950 224475
#3     3  30975 292625

正如@akrun 提到的, 简单地使用 xtabs

xtabs(amount~rankP+defaulted, df)

使用 tidyr::pivot_wider 你可以做到 -

tidyr::pivot_wider(df, names_from = defaulted, values_from = amount, 
                       values_fn = sum, values_fill = 0)

#  rankP    `1`    `0`
#  <int>  <int>  <int>
#1     1 593450 157850
#2     2 224475  93950
#3     3 292625  30975