【问题标题】:Grouped pivot_longer dplyr分组 pivot_longer dplyr
【发布时间】:2020-06-14 09:18:20
【问题描述】:

这是一个示例数据框。我的真实数据框更大。我非常喜欢 tidyverse 解决方案。

#my data
age <- c(18,18,19)
A1 <- c(3,5,3)
A2 <- c(4,4,3)
B1 <- c(1,5,2)
B2 <- c(2,2,5)
df <- data.frame(age, A1, A2, B1, B2)

我希望我的数据如下所示:

#what i want
new_age <- c(18,18,18,18,19,19)
A <- c(3,5,4,4,3,3)
B <- c(1,5,2,2,2,5)
new_df <- data.frame(new_age, A, B)

我想旋转更长的时间并将 A1:A2 列堆叠到 A 列中,将 B1:B2 列堆叠到 B 列中。我还希望得到与正确年龄相匹配的响应。例如,本例中 19 岁的人在 A1:A2 列中只回答了 3。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:
    tidyr::pivot_longer(df, cols = -age, names_to = c(".value",'groupid'), 
                        #1+ non digits followed by 1+ digits
                        names_pattern = "(\\D+)(\\d+)")
    # A tibble: 6 x 4
        age groupid   A     B
      <dbl> <chr> <dbl> <dbl>
    1    18 1         3     1
    2    18 2         4     2
    3    18 1         5     5
    4    18 2         4     2
    5    19 1         3     2
    6    19 2         3     5
    

    【讨论】:

    • 1) 对于我可以在哪里了解有关 names_pattern 输入的更多信息,您有什么建议吗?我对 pivot_longer 还不太满意。 2) 你可以在names_pattern 中使用starts_with 吗?编辑:我将研究 extract() 和 pivot_longer_spec() tidyr.tidyverse.org/reference/pivot_longer.html
    • 请参阅here 了解tidyrnames_pattern,您需要熟悉正则表达式,您可以在this stringr 教程中找到。关于 2:不,我们不能使用 start_with,因为我们告诉 pivot_longer 如何创建新组“列”
    【解决方案2】:

    在 Base R 中,您将使用 reshape,然后选择您想要的列。您也可以更改行名

    reshape(df,2:ncol(df),dir = "long",sep="")[,-c(2,5)] # 
        age A B
    1.1  18 3 1
    2.1  18 5 5
    3.1  19 3 2
    1.2  18 4 2
    2.2  18 4 2
    3.2  19 3 5
    

    【讨论】:

      【解决方案3】:

      由于您拥有更大的数据框,因此data.table 的解决方案可能会更快。在这里,您可以使用 data.table 包中的 melt 函数,如下所示:

      library(data.table)
      colA = grep("A",colnames(df),value = TRUE)
      colB = grep("B",colnames(df),value = TRUE)
      setDT(df)
      
      df <- melt(df, measure = list(colA,colB), value.name = c("A","B"))
      df[,variable := NULL]
      dt <- dt[order(age)]
      
         age A B
      1:  18 3 1
      2:  18 5 5
      3:  18 4 2
      4:  18 4 2
      5:  19 3 2
      6:  19 3 5
      

      它回答了你的问题吗?

      编辑:使用模式 - @Wimpel 的建议

      正如@Wimpel 在 cmets 中建议的那样,您可以使用模式获得相同的结果:

      melt( setDT(df), measure.vars = patterns( A="^A[0-9]", B="^B[0-9]") )[, variable:=NULL][]
      
         age A B
      1:  18 3 1
      2:  18 5 5
      3:  19 3 2
      4:  18 4 2
      5:  18 4 2
      6:  19 3 5
      

      【讨论】:

      • 或使用patterns 喜欢:melt( setDT(df), measure.vars = patterns( A="^A[0-9]", B="^B[0-9]") )[, variable:=NULL][]
      • 不错!感谢您的建议,我会将其添加到我的答案中。我不知道如何将多个命令组合成一行。
      猜你喜欢
      • 1970-01-01
      • 2021-05-02
      • 2022-11-24
      • 1970-01-01
      • 1970-01-01
      • 2020-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多