我有以下数据
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_longer和pivot_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,分别。
您可以使用 :
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)