【问题标题】:Reshape Data Long to Wide - understanding reshape parametersReshape Data Long to Wide - 了解 reshape 参数
【发布时间】:2015-11-21 03:18:53
【问题描述】:

我有一个长格式的数据框狗,我正在尝试使用 reshape() 函数将其重新格式化为宽格式。目前看起来是这样的:

dogid  month  year  trainingtype  home  school  timeincomp
12345  1      2014  1             1     1       340
12345  2      2014  1             1     1       360
31323  12     2015  2             7     3       440
31323  1      2014  1             7     3       500
31323  2      2014  1             7     3       520

dogid 列是一组 id,每只狗一个。 12 个月的月份列从 1 到 12 变化,2014 到 2015 年的年份变化。Trainingtype 从 1 到 2 变化。每只狗的每个月-年-trainingtype 组合都有一个 timeincomp 值,因此每只狗有 48 个条目。家庭和学校从 1 到 8 不等,并且每只狗都是不变的(同一只狗的每个条目都有相同的学校和家庭)。参加比赛的时间是我的反应变量。

我希望我的桌子看起来像这样:

dogid  home  school  month1year2014trainingtype1  month2year2014trainingtype1
12345  1     1       340                          360
31323  7     3       500                          520

等等。 (每个月-年-培训类型组合的列)

我应该在 reshape 中使用哪些参数来实现这一点?

【问题讨论】:

    标签: r format reshape reshape2 tidyr


    【解决方案1】:

    您可以使用包reshape2 中的函数dcast。更容易理解。公式左边是长的,右边是宽的。

    fun.aggregate 是在每个案例有超过 1 个数字的情况下应用的函数。如果确定没有重复病例,可以使用meansum

    dcast(data, formula= dogid + home + school ~ month + year + trainingtype,
    value.var = 'timeincomp',
    fun.aggregate = sum)
    

    我希望它有效:

      dogid home school 1_2014_1 2_2014_1 12_2015_2
    1 12345    1      1      340      360         0
    2 31323    7      3      500      520       440
    

    【讨论】:

      【解决方案2】:

      在这种情况下,使用基数 reshape,您实际上需要三个时间变量的 interaction() 来定义您的宽变量,所以:

      idvars  <- c("dogid","home","school")
      grpvars <- c("year","month","trainingtype")
      outvar  <- "timeincomp"
      time    <- interaction(dat[grpvars])
      
      reshape(
        cbind(dat[c(idvars,outvar)],time),
        idvar=idvars,
        timevar="time",
        direction="wide"
      )
      
      #  dogid home school timeincomp.2014.1.1 timeincomp.2014.2.1 timeincomp.2015.12.2
      #1 12345    1      1                 340                 360                   NA
      #3 31323    7      3                 500                 520                  440
      

      【讨论】:

        【解决方案3】:

        您可以使用reshape2tidyr 的新替代品来做同样的事情:

        library(tidyr)
        library(dplyr)
        data %>% unite(newcol, c(year, month, trainingtype)) %>%
                 spread(newcol, timeincomp)
        
          dogid home school 2014_1_1 2014_2_1 2015_12_2
        1 12345    1      1      340      360        NA
        2 31323    7      3      500      520       440
        

        首先,我们将年、月和培训类型列合并到一个名为 newcol 的新列中,然后以 timeincomp 作为我们的值变量来传播数据。

        NA 在那里,因为我们没有任何值,您可以通过在扩展函数中更改 fill = NA 来给它一个。

        【讨论】:

        • 我仍然不习惯 tidyr,并试图将gather() 与 spread() 结合起来,但还没有看到'unite() 是必要的!谢谢!
        【解决方案4】:

        对于 tidyr_1.0.0 及以上版本,另一个选项是 pivot_wider

        library(tidyverse)
        
        df <- tribble(
        ~dogid, ~month, ~year, ~trainingtype, ~home, ~school, ~timeincomp,
        12345,  1,  2014, 1, 1, 1, 340,
        12345,  2,  2014, 1, 1, 1, 360,
        31323,  12, 2015, 2, 7, 3, 440,
        31323,  1,  2014, 1, 7, 3, 500,
        31323,  2,  2014, 1, 7, 3, 520
        )
        
        
        df %>% pivot_wider(
          id_cols = c(dogid,home, school),
          names_from = c(month, year, trainingtype),
          values_from = c(timeincomp),
        )
        

        【讨论】:

          猜你喜欢
          • 2022-11-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-11
          相关资源
          最近更新 更多