如何使用R将行转换为镜像SAS实现的列?

时间:2016-01-14 23:12:09

标签: r sas

我已经搜索了相当长的一段时间,并且无法找到一种似乎不会让我失望的方式。 我试图在R中复制following SAS implementation

现在我正试图弄清楚如何在没有聚合的情况下转置基于多个识别字段的多个值。

示例起点:

Cat1  Cat2      Cat3    Date        Occ  Dur
A00   Group1    Sub1    2015-05-09  1    30
A00   Group1    Sub1    2015-09-09  2    30
A00   Group1    Sub2    2015-06-23  1    60
B00   Group1    Sub1    2015-07-30  3    30
B00   Group1    Sub2    2015-03-25  1    60
B00   Group1    Sub2    2015-02-14  2    60

我希望获得以下输出:

Cat1    Cat2    Cat3    Date1       Date2       Occ1    Occ2    Dur1  Dur2
A00     Group1  Sub1    2015-05-09  2015-09-09  1       2         30    30
A00     Group1  Sub2    2015-06-23              1                 60      
B00     Group1  Sub1    2015-07-30              3                 30      
B00     Group1  Sub2    2015-03-25  2015-02-14  1       2         60    60

我意识到不同的环境可能需要不同的方法。我确实对替代解决方案持开放态度,而不是直接尝试在SAS中复制逻辑。我已经尝试过各种尝试用熔化和铸造重塑数据而没有任何运气。任何帮助都将非常感谢!

2 个答案:

答案 0 :(得分:1)

这是一个基于data.table的解决方案,它非常接近地模仿逻辑:

library(data.table)
library(reshape2)

DT <- fread("Cat1    Cat2    Cat3    Date    Occ Dur
            A00 Group1  Sub1    2015-05-09  1   30
            A00 Group1  Sub1    2015-09-09  2   30
            A00 Group1  Sub2    2015-06-23  1   60
            B00 Group1  Sub1    2015-07-30  3   30
            B00 Group1  Sub2    2015-03-25  1   60
            B00 Group1  Sub2    2015-02-14  2   60")


DTw <- dcast(
  melt(DT, id.vars = c("Cat1", "Cat2", "Cat3"))[
    , Idx := 1:.N
    , keyby = .(Cat1,Cat2, Cat3, variable)
    ]
  , Cat1 + Cat2 + Cat3 ~ variable + Idx)

DTw

结果如下:

  Cat1   Cat2 Cat3     Date_1     Date_2 Occ_1 Occ_2 Dur_1 Dur_2
1  A00 Group1 Sub1 2015-05-09 2015-09-09     1     2    30    30
2  A00 Group1 Sub2 2015-06-23       <NA>     1  <NA>    60  <NA>
3  B00 Group1 Sub1 2015-07-30       <NA>     3  <NA>    30  <NA>
4  B00 Group1 Sub2 2015-03-25 2015-02-14     1     2    60    60

答案 1 :(得分:1)

这是dpyrtidyr解决方案。可能有一种方法可以更干净地完成这项工作,但它确实有效。它会产生关于id() is deprecated的警告,我不知道如何摆脱它

library(dplyr)
library(tidyr)

df %>%
   gather(key, value, -c(Cat1:Cat3)) %>%  ## Put in long format
   group_by(Cat1, Cat2, Cat3, key)   %>%  ## Group for numbering (1,2)
   mutate(rn = row_number())         %>%  ## Add row numbers to unite with key column
   unite(new_key, key, rn, sep = '') %>%  ## Make new unique key to be col name
   spread(new_key, value, fill = '') %>%  ## Put in 'wide' format
   select(Cat1, Cat2, Cat3, Date1, Date2, Occ1, Occ2, Dur1, Dur2)  # re-order columns

结果

  Cat1   Cat2 Cat3      Date1      Date2 Occ1 Occ2 Dur1 Dur2
1  A00 Group1 Sub1 2015-05-09 2015-09-09    1    2   30   30
2  A00 Group1 Sub2 2015-06-23               1        60     
3  B00 Group1 Sub1 2015-07-30               3        30     
4  B00 Group1 Sub2 2015-03-25 2015-02-14    1    2   60   60