Reputation: 905
I have a dataframe where rows are persons, and columns are how they responded in multiple option questions:
df <- data.frame(person = c("A", "B", "C"), question_1 = c(1, 3, 2), question_2 = c(1, 1, 2))
> df
person question_1 question_2
1 A 1 1
2 B 3 1
3 C 2 2
I need to pivot_wider
this table in the following way: each value of the original table becomes a column, and the values of the new table are whether the option was chosen (0 = not chosen, 1 = chosen). The final output should look this way:
person q1_1 q1_2 q1_3 q2_1 q2_2
1 A 1 0 0 1 0
2 B 0 0 1 1 0
3 C 0 1 0 0 1
>
I've tried with pivot_wider(df, names_from = c(question_1, question_2))
, but it doesn't work. Any suggestions?
Upvotes: 2
Views: 158
Reputation: 79208
In base R you could do:
with(stack(df[-1]), table(cbind(df[1], q = sprintf("q%s_%d", gsub("\\D", "", ind), values))))
q
person q1_1 q1_2 q1_3 q2_1 q2_2
A 1 0 0 1 0
B 0 0 1 1 0
C 0 1 0 0 1
Upvotes: 2
Reputation: 887048
We could reshape to 'long' format before converting to 'wide
library(dplyr)
library(tidyr)
library(stringr)
df %>%
pivot_longer(cols = -person) %>%
mutate(name = str_c('q', str_extract(name, "\\d"), "_", value), value = 1) %>%
pivot_wider(names_from = name, values_from = value, values_fill = 0) %>%
select(gtools::mixedorder(names(.)))
-output
# A tibble: 3 x 6
# person q1_1 q1_2 q1_3 q2_1 q2_2
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 A 1 0 0 1 0
#2 B 0 0 1 1 0
#3 C 0 1 0 0 1
Upvotes: 2