Mam dane z ankiety internetowej, w której respondenci 1-3 razy przechodzą przez pętlę pytań. Program badania (Qualtrics) zapisuje te dane w wielu kolumnach, to znaczy Q3.2 w badaniu będą miały kolumny Q3.2.1.
, Q3.2.2.
oraz Q3.2.3.
:
df <- data.frame(
id = 1:10,
time = as.Date('2009-01-01') + 0:9,
Q3.2.1. = rnorm(10, 0, 1),
Q3.2.2. = rnorm(10, 0, 1),
Q3.2.3. = rnorm(10, 0, 1),
Q3.3.1. = rnorm(10, 0, 1),
Q3.3.2. = rnorm(10, 0, 1),
Q3.3.3. = rnorm(10, 0, 1)
)
# Sample data
id time Q3.2.1. Q3.2.2. Q3.2.3. Q3.3.1. Q3.3.2. Q3.3.3.
1 1 2009-01-01 -0.2059165 -0.29177677 -0.7107192 1.52718069 -0.4484351 -1.21550600
2 2 2009-01-02 -0.1981136 -1.19813815 1.1750200 -0.40380049 -1.8376094 1.03588482
3 3 2009-01-03 0.3514795 -0.27425539 1.1171712 -1.02641801 -2.0646661 -0.35353058
...
Chcę połączyć wszystkie kolumny QN.N * w uporządkowane oddzielne kolumny QN.N, ostatecznie kończąc na czymś takim:
id time loop_number Q3.2 Q3.3
1 1 2009-01-01 1 -0.20591649 1.52718069
2 2 2009-01-02 1 -0.19811357 -0.40380049
3 3 2009-01-03 1 0.35147949 -1.02641801
...
11 1 2009-01-01 2 -0.29177677 -0.4484351
12 2 2009-01-02 2 -1.19813815 -1.8376094
13 3 2009-01-03 2 -0.27425539 -2.0646661
...
21 1 2009-01-01 3 -0.71071921 -1.21550600
22 2 2009-01-02 3 1.17501999 1.03588482
23 3 2009-01-03 3 1.11717121 -0.35353058
...
tidyr
Biblioteka posiada gather()
funkcję, która działa świetnie na łączenie jeden zestaw kolumn:
library(dplyr)
library(tidyr)
library(stringr)
df %>% gather(loop_number, Q3.2, starts_with("Q3.2")) %>%
mutate(loop_number = str_sub(loop_number,-2,-2)) %>%
select(id, time, loop_number, Q3.2)
id time loop_number Q3.2
1 1 2009-01-01 1 -0.20591649
2 2 2009-01-02 1 -0.19811357
3 3 2009-01-03 1 0.35147949
...
29 9 2009-01-09 3 -0.58581232
30 10 2009-01-10 3 -2.33393981
Wynikowa ramka danych ma 30 wierszy, zgodnie z oczekiwaniami (10 osobników, 3 pętle każda). Jednak gromadzenie drugiego zestawu kolumn nie działa poprawnie - pomyślnie tworzy dwie połączone kolumny Q3.2
i Q3.3
, ale kończy się na 90 wierszach zamiast 30 (wszystkie kombinacje 10 osobników, 3 pętle Q3.2 i 3 pętle Q3 .3; kombinacje znacznie wzrosną dla każdej grupy kolumn w rzeczywistych danych):
df %>% gather(loop_number, Q3.2, starts_with("Q3.2")) %>%
gather(loop_number, Q3.3, starts_with("Q3.3")) %>%
mutate(loop_number = str_sub(loop_number,-2,-2))
id time loop_number Q3.2 Q3.3
1 1 2009-01-01 1 -0.20591649 1.52718069
2 2 2009-01-02 1 -0.19811357 -0.40380049
3 3 2009-01-03 1 0.35147949 -1.02641801
...
89 9 2009-01-09 3 -0.58581232 -0.13187024
90 10 2009-01-10 3 -2.33393981 -0.48502131
Czy istnieje sposób na użycie wielu wywołań w gather()
tym celu, łącząc małe podzbiory kolumn, jak to, przy jednoczesnym zachowaniu prawidłowej liczby wierszy?
seperate()
aby podzielić wartości Q3.3 (i nie tylko) na ich własne kolumny. Ale to wciąż wydaje się być naprawdę okrężnym, hakerskim rozwiązaniem…
spread
Pracuję teraz nad rozwiązaniem: p
df %>% gather(question_number, Q3.2, starts_with("Q3.")) %>% mutate(loop_number = str_sub(question_number,-2,-2), question_number = str_sub(question_number,1,4)) %>% select(id, time, loop_number, question_number, Q3.2) %>% spread(key = question_number, value = Q3.2)
spread()
. Chociaż wielokrotne połączenia i tak wydają się nieuniknione, niezależnie od tego, czy działa kilka połączeń generate()
, czy zagnieżdżone spread()
…
df %>% gather(loop_number, Q3.2, starts_with("Q3."))