Saya memiliki data dari survei online di mana responden melewati putaran pertanyaan 1-3 kali. Perangkat lunak survei (Qualtrics) mencatat data ini dalam beberapa kolom-yaitu, Q3.2 dalam survei akan memiliki kolom Q3.2.1.
, Q3.2.2.
dan 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
...
Saya ingin menggabungkan semua kolom QN.N * menjadi kolom QN.N individual yang rapi, yang pada akhirnya berakhir dengan sesuatu seperti ini:
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
...
The tidyr
perpustakaan memiliki gather()
fungsi, yang bekerja bagus untuk menggabungkan satu set kolom:
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
Bingkai data yang dihasilkan memiliki 30 baris, seperti yang diharapkan (10 individu, masing-masing 3 loop). Namun, mengumpulkan kumpulan kolom kedua tidak berfungsi dengan benar — ini berhasil membuat dua kolom gabungan Q3.2
dan Q3.3
, tetapi berakhir dengan 90 baris, bukan 30 (semua kombinasi 10 individu, 3 loop Q3.2, dan 3 loop Q3 .3; kombinasi akan meningkat secara substansial untuk setiap kelompok kolom dalam data aktual):
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
Adakah cara untuk menggunakan beberapa panggilan untuk gather()
seperti ini, menggabungkan subkumpulan kecil kolom seperti ini sambil mempertahankan jumlah baris yang benar?
seperate()
untuk membagi nilai Q3.3 (dan seterusnya) ke dalam kolom mereka sendiri. Tapi itu masih tampak seperti solusi yang tidak benar-benar bundar…
spread
saya sedang mengerjakan solusi sekarang: 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()
. Meskipun beberapa panggilan tampaknya tak terhindarkan, baik itu sekumpulan panggilan generate()
yang berhasil atau bertingkat spread()
...
df %>% gather(loop_number, Q3.2, starts_with("Q3."))