r-求和时从长到宽的重新整形



我有以下示例数据

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() 来完成它

实现这一目标的方法是什么?

使用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)

您可以使用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)(。

使用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

相关内容

  • 没有找到相关文章

最新更新