【问题标题】:Create a transpose table from data frame从数据框创建转置表
【发布时间】:2021-03-03 19:20:45
【问题描述】:

我有一个包含以下示例数据的大数据库。我正在尝试创建一个函数,该函数可以从 Dept 列中逐一过滤 Dept,并且从过滤的子集数据中为所有过滤的经理创建一个表,如下所示。

dept 的管理者可以有很多或更少,因此它可以为过滤的管理者动态创建表。因为有时部门经理可能是 1-23 岁或更多。

我尝试帮助过滤和转置数据,然后绑定它,但这对我来说不能正常工作,因为我只精通 dplyr。

df <- data.frame(Dept = c("CA","HR","CA","HR","HR","CA","HR","HR","CA","CA","HR","CA","CA"),
                 Manager = c("AKASH","MANU","AMAN","SANU","NISH","KAMAL","VEER","SANIL","SAMEER","KANU","NUKUL","KUNAL","RAMIT"),
                 PF = c("Yes","No","Yes","Yes","Yes","No","No","Yes","No","Yes","Yes","Yes","No"),
                 Yearlybonus=c(6946,5871,0,7173,2161,3008,0,3025,4323,4196,0,5594,2313),
                 Quaterlybonus=c(2683,3846,0,2391,6716,6012,5479,3869,3764,0,4632,0,2371),
                 monthlybonus=c(4453,6466,2811,6845,4377,2617,0,7631,7761,2944,6270,3534,5856))

【问题讨论】:

    标签: r function dplyr


    【解决方案1】:

    使用data.table 处理大型数据集

    此解决方案不会将转换后的数据累积为列表。相反,它使用了一个过滤数据的函数

    library('data.table')
    setDT(df)
    df[, `:=`(Yearlybonus = as.character(Yearlybonus),
             Quaterlybonus = as.character(Quaterlybonus), 
             monthlybonus = as.character(monthlybonus))]
    

    这个函数是一个纯函数,因为它每次都会向函数发送一份数据(df)的副本。如果您的内存空间较少,您可以重构此函数以使用全局范围内的数据 (df)。重构后的代码看起来像注释行中的代码。

    # myfun <- function(x) {
    myfun <- function(df, x) {
      # wide to long
      # y <- melt( df[Dept == x], 
      df <- melt( df[Dept == x], 
                 id.vars = c('Manager'), 
                 measure.vars = c('PF', 'Yearlybonus', 'Quaterlybonus', 'monthlybonus'), 
                 variable.name = 'T' )
      # long to wide
      # y <- dcast(y, T ~ Manager, value.var = 'value')
      df <- dcast(df, T ~ Manager, value.var = 'value')
    
      # add dept column
      #y[, Dept := x ]
      df[, Dept := x ]
    
      # set column order in memory
      #nm <- names(y)
      nm <- names(df)
      nm <- c('Dept', nm[nm != 'Dept'])
      #setcolorder(y, nm)
      setcolorder(df, nm)
    
      #return(y[])
      return(df[])    }
    }
    
    # create index for speed
    setkey(df, Dept)
    
    # myfun(x = 'CA')   
    myfun(df = df, x = 'CA')
    
    #  Dept             T AKASH AMAN KAMAL KANU KUNAL RAMIT SAMEER
    #1:   CA            PF   Yes  Yes    No  Yes   Yes    No     No
    #2:   CA   Yearlybonus  6946    0  3008 4196  5594  2313   4323
    #3:   CA Quaterlybonus  2683    0  6012    0     0  2371   3764
    #4:   CA  monthlybonus  4453 2811  2617 2944  3534  5856   7761
    
    # myfun(x = 'HR')   
    myfun(df = df, x = 'HR')
    #   Dept             T MANU NISH NUKUL SANIL SANU VEER
    #1:   HR            PF   No  Yes   Yes   Yes  Yes   No
    #2:   HR   Yearlybonus 5871 2161     0  3025 7173    0
    #3:   HR Quaterlybonus 3846 6716  4632  3869 2391 5479
    #4:   HR  monthlybonus 6466 4377  6270  7631 6845    0
    

    【讨论】:

      【解决方案2】:

      这个怎么样:

      library(tidyr)
      library(dplyr)
      library(purrr)
      map(unique(df$Dept), ~df %>% filter(Dept == .x) %>% 
        mutate(across(Yearlybonus:monthlybonus, ~as.character(.x))) %>% 
        pivot_longer(PF:monthlybonus, names_to="T", values_to="vals") %>% 
        pivot_wider(names_from="Manager", values_from="vals"))
      
      
      # [[1]]
      # # A tibble: 4 x 9
      #   Dept  T             AKASH AMAN  KAMAL SAMEER KANU  KUNAL RAMIT
      #   <chr> <chr>         <chr> <chr> <chr> <chr>  <chr> <chr> <chr>
      # 1 CA    PF            Yes   Yes   No    No     Yes   Yes   No   
      # 2 CA    Yearlybonus   6946  0     3008  4323   4196  5594  2313 
      # 3 CA    Quaterlybonus 2683  0     6012  3764   0     0     2371 
      # 4 CA    monthlybonus  4453  2811  2617  7761   2944  3534  5856 
      # 
      # [[2]]
      # # A tibble: 4 x 8
      #   Dept  T             MANU  SANU  NISH  VEER  SANIL NUKUL
      #   <chr> <chr>         <chr> <chr> <chr> <chr> <chr> <chr>
      # 1 HR    PF            No    Yes   Yes   No    Yes   Yes  
      # 2 HR    Yearlybonus   5871  7173  2161  0     3025  0    
      # 3 HR    Quaterlybonus 3846  2391  6716  5479  3869  4632 
      # 4 HR    monthlybonus  6466  6845  4377  0     7631  6270 
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-29
        • 2021-12-22
        • 2020-02-23
        • 2020-09-19
        • 1970-01-01
        相关资源
        最近更新 更多