【问题标题】:R tidyr gather() two sets of columns based on lookupR tidyr gather() 基于查找的两组列
【发布时间】:2019-05-27 18:57:30
【问题描述】:

我有一个按地区划分的满意度调查结果数据集。调查中的每个问题都按 4 分制进行评分(从非常满意非常不满意)。数据集中的每一行都包含给定“财政年度”结束时给定区域中给定问题的汇总结果。它还包含每个级别的受访者总数。

这就是数据集的样子

testdf=data.frame(FY=c("FY13","FY14","FY15","FY14","FY15","FY13","FY14","FY15","FY13","FY15","FY13","FY14","FY15","FY13","FY14","FY15"),
                  Region=c(rep("AFRICA",5),rep("ASIA",5),rep("AMERICA",6)),
                  QST=c(rep("Q2",3),rep("Q5",2),rep("Q2",3),rep("Q5",2),rep("Q2",3),rep("Q5",3)),
                  Very.Satisfied=runif(16,min = 0, max=1),
                  Total.Very.Satisfied=floor(runif(16,min=10,max=120)),
                  Satisfied=runif(16,min = 0, max=1),
                  Total.Satisfied=floor(runif(16,min=10,max=120)),
                  Dissatisfied=runif(16,min = 0, max=1),
                  Total.Dissatisfied=floor(runif(16,min=10,max=120)),
                  Very.Dissatisfied=runif(16,min = 0, max=1),
                  Total.Very.Dissatisfied=floor(runif(16,min=10,max=120))
                  )

我的目标

我的目标是将数据集从宽格式重塑为长格式,首先创建一个名为Level 的列(表示来自 4 点刻度的级别)。然后创建一个名为Score 的列,其中包含汇总分数,最后一列名为Total,其中包含每个相应级别的受访者总数。

我的尝试

到目前为止,我刚刚能够将gather 级别 合并到一个列中,并创建Score 列。

#Gather Satisfation levels
library(tidyverse)
testfinal = testdf %>% gather(Level,Score,-FY:-QST,-Total.Very.Satisfied,-Total.Satisfied,-Total.Dissatisfied,-Total.Very.Dissatisfied) %>%
  select(1:3,8:9,4:7)

我无法弄清楚如何将gather总数放入另一列这样新创建的每个总数 @987654329 @column 对应与其关联的级别。

这里是最终数据集的预览,如果一切顺利的话

#FY   #Region  #QST  #Level            #Score        #Total
 FY13  AFRICA   Q2    Very.Satisfied    0.73080770    48
 FY14  AFRICA   Q2    Very.Satisfied    0.58686424    97
 FY15  AFRICA   Q2    Very.Satisfied    0.07358698    34
 FY14  AFRICA   Q5    Very.Satisfied    0.59996830    22

等等……

我们将不胜感激。

【问题讨论】:

    标签: r tidyr data-manipulation


    【解决方案1】:

    使用来自data.tablemelt 可以更轻松地完成此操作。将“data.frame”转换为“data.table”(setDT),将melt从“wide”转换为“long”,同时在measure参数中指定多列名称patterns

    library(data.table)
    out <- melt(setDT(testdf), measure = patterns("^Total", 
         "^(Very|Satisfied|Dis)"), value.name = c("Total", "Score"), 
           variable.name = "Level")
    nm1 <- names(testdf)[c(4, 6, 8, 10)]
    out[, Level := nm1[Level]][]
    head(out)
    #     FY Region QST          Level Total      Score
    #1: FY13 AFRICA  Q2 Very.Satisfied    85 0.36888202
    #2: FY14 AFRICA  Q2 Very.Satisfied   108 0.67589979
    #3: FY15 AFRICA  Q2 Very.Satisfied    13 0.90792351
    #4: FY14 AFRICA  Q5 Very.Satisfied    52 0.01966743
    #5: FY15 AFRICA  Q5 Very.Satisfied    59 0.68895083
    #6: FY13   ASIA  Q2 Very.Satisfied    96 0.24912066
    

    或使用tidyverse

    library(tidyverse)
    testdf %>%
        gather(key, val, 4:ncol(.)) %>%
        extract(key, into = c("key1", "Level"), "(Total)?\\.?(.*)") %>%
        mutate(key1 = replace_na(key1, "Score")) %>%
        spread(key1, val)
    #      FY  Region QST             Level      Score Total
    #1  FY13  AFRICA  Q2      Dissatisfied 0.69226483    71
    #2  FY13  AFRICA  Q2         Satisfied 0.91617425    26
    #3  FY13  AFRICA  Q2 Very.Dissatisfied 0.64277110    43
    #4  FY13  AFRICA  Q2    Very.Satisfied 0.36888202    85
    #5  FY13 AMERICA  Q2      Dissatisfied 0.10219036    37
    #6  FY13 AMERICA  Q2         Satisfied 0.28281065    26
    #7  FY13 AMERICA  Q2 Very.Dissatisfied 0.59667659    90
    #8  FY13 AMERICA  Q2    Very.Satisfied 0.30204224    76
    # ....
    

    注意:“Total”、“Score”中的值不同,因为在创建数据集时没有 set.seed

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 2015-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多