tidyverse hub_longer 几组列,但避免中间的 mutate_wider 步骤

des*_*hen 3 pivot r tidyr

我有以下数据

dat <- data.frame(id         = c("A", "B", "C"),
                  Q1r1_pepsi = c(1,0,1),
                  Q1r1_cola  = c(0,0,1),
                  Q1r2_pepsi = c(1,1,1),
                  Q1r2_cola  = c(0,1,1),
                  stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)

其中 Q1r1 和 Q1r2 是调查中的评级问题,百事可乐和可乐是被评级的品牌。所以我对两个品牌(百事可乐、可乐)有两个评级(r1 和 r2):

id      Q1r1_c1    Q1r1_c2    Q1r2_c1    Q1r2_c2
"A"     1          0          1          0
"B"     0          0          1          1
"C"     1          1          1          1
Run Code Online (Sandbox Code Playgroud)

dat(附带问题:如何格式化 SO 帖子,以便它正确包含在 R 控制台中调用时获得的格式良好的输出?)

为了分析数据,我需要重塑(旋转)数据,以便行指示唯一的评级品牌对。因此,预期结果将是:

id      brand   Q1r1    Q1r2
"A"     "pepsi" 1       1
"A"     "cola"  0       0
"B"     "pepsi" 0       1
"B"     "cola"  0       1
"C"     "pepsi" 1       1
"C"     "cola"  1       1
Run Code Online (Sandbox Code Playgroud)

目前,我总是结合使用pivot_longerpivot_wider,但我希望我可以通过pivoting_longer直接得到这个结果,而不需要做中间步骤:

library(tidyverse)

dat_long <- dat %>%
  pivot_longer(cols = starts_with("Q1")) %>%
  separate(name, into = c("item", "brand"), remove = FALSE)

dat_wide <- dat_long %>%
  pivot_wider(id_cols = c(id, brand),
              names_from = item,
              values_from = value)
Run Code Online (Sandbox Code Playgroud)

对于当前的示例,执行此中间步骤仍然可以,但在其他不太干净的示例中会变得很烦人,例如假设我的列没有以良好的结构命名Q1r1_c1, Q1r1_c2, Q1r2_c1, Q1r2_c2,而是在Q4, Q5, Q8r1, Q8r2地图位于 Q4 和 Q8r1 之间的位置,和Q5/Q8r2,分别。

Ron*_*hah 5

您可以使用 :

tidyr::pivot_longer(dat, cols = -id, 
                   names_to = c('.value', 'brand'), 
                   names_sep = "_")


#  id    brand  Q1r1  Q1r2
#  <chr> <chr> <dbl> <dbl>
#1 A     pepsi     1     1
#2 A     cola      0     0
#3 B     pepsi     0     1
#4 B     cola      0     1
#5 C     pepsi     1     1
#6 C     cola      1     1
Run Code Online (Sandbox Code Playgroud)