如何在 R(或 Excel)中执行这种独特的重塑?

bri*_*evk 3 excel r reshape dataframe

我正在尝试重塑数据框,并且该任务与典型的重塑完全不同,我无法完全改变它。该表最初是在 Excel 中,但我已经导入到 R 中,因此我可以在任一软件中使用解决方案。

我有一个donors包含名称、值和月份的数据框:

NAME    AMT    MONTH
brett   100    jan
brett   100    mar
brett   100    nov
brett   50     apr
brett   50     jun
jane    75     dec
sam     200    jan
sam     200    feb
sam     200    mar
Run Code Online (Sandbox Code Playgroud)

我需要重塑此数据框,以便有一个 NAME 列、一个 AMT 列和每个月的列。每行对应于名称和金额都唯一的任何观察,月份列是二元变量(如果该捐赠者/金额组合发生在该月,则为 1,如果没有,则为 0。

所以上面的例子可以得出:

NAME   AMT   JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
brett  100   1   0   1   0   0   0   0   0   0   0   1   0
brett  50    0   0   0   1   0   1   0   0   0   0   0   0
jane   75    0   0   0   0   0   0   0   0   0   0   0   1
sam    200   1   1   1   0   0   0   0   0   0   0   0   0
Run Code Online (Sandbox Code Playgroud)

如果您想完成我的代码,请创建一个最终列,该列等于 NAME/AMT 组合发生的总次数(仅等于月份列的总和)...但如果您不这样做,我可以自己做感觉它。

谢谢你!

Ron*_*hah 5

这是一个tidyverse尝试 -

  • complete创建缺少月份的行。
  • arrange以便您的列顺序正确。
  • 使用 获取宽格式数据pivot_wider
library(dplyr)
library(tidyr)

df %>%
  complete(MONTH = tolower(month.abb)) %>%
  arrange(match(MONTH, tolower(month.abb))) %>%
  pivot_wider(names_from = MONTH, values_from = MONTH, 
              values_fn = length, values_fill = 0) %>%
  na.omit

#  NAME    AMT   jan   feb   mar   apr   may   jun   jul   aug   sep   oct   nov   dec
#  <chr> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#1 brett   100     1     0     1     0     0     0     0     0     0     0     1     0
#2 sam     200     1     1     1     0     0     0     0     0     0     0     0     0
#3 brett    50     0     0     0     1     0     1     0     0     0     0     0     0
#4 jane     75     0     0     0     0     0     0     0     0     0     0     0     1
Run Code Online (Sandbox Code Playgroud)

请注意,这month.abb是内置的 R 向量,它给出了缩写的月份名称。我曾经tolower(month.abb)将其与数据中的实际列名进行匹配。

数据

df <- structure(list(NAME = c("brett", "brett", "brett", "brett", "brett", 
"jane", "sam", "sam", "sam"), AMT = c(100L, 100L, 100L, 50L, 
50L, 75L, 200L, 200L, 200L), MONTH = c("jan", "mar", "nov", "apr", 
"jun", "dec", "jan", "feb", "mar")), 
class = "data.frame", row.names = c(NA, -9L))
Run Code Online (Sandbox Code Playgroud)