Tôi có dữ liệu từ một cuộc khảo sát trực tuyến trong đó người trả lời đi qua một vòng câu hỏi 1-3 lần. Các phần mềm khảo sát (Qualtrics) ghi lại dữ liệu này trong nhiều cột-có nghĩa là, Q3.2 trong cuộc khảo sát sẽ có cột Q3.2.1.
, Q3.2.2.
và 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
...
Tôi muốn kết hợp tất cả các cột QN.N * thành các cột QN.N riêng lẻ gọn gàng, cuối cùng kết thúc bằng một cái gì đó như sau:
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
...
Các tidyr
thư viện có gather()
chức năng, trong đó hoạt động tuyệt vời để kết hợp một loạt các cột:
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
Khung dữ liệu kết quả có 30 hàng, như mong đợi (10 cá thể, mỗi vòng 3 vòng). Tuy nhiên, việc thu thập tập hợp cột thứ hai không hoạt động chính xác — nó làm cho hai cột được kết hợp thành côngQ3.2
và Q3.3
nhưng kết thúc với 90 hàng thay vì 30 (tất cả các kết hợp của 10 cá nhân, 3 vòng của Q3.2 và 3 vòng của Q3 .3; các kết hợp sẽ tăng đáng kể cho mỗi nhóm cột trong dữ liệu thực tế):
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
Có cách nào để sử dụng nhiều lệnh gọi gather()
như thế này, kết hợp các tập hợp con nhỏ của các cột như thế này trong khi vẫn duy trì số hàng chính xác không?
seperate()
để chia các giá trị Q3.3 (và hơn thế nữa) thành các cột của riêng chúng. Nhưng đó vẫn có vẻ như là một giải pháp hacky thực sự vòng vo…
spread
tôi đang làm việc trên một giải pháp bây giờ: 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()
. Mặc dù nhiều cuộc gọi xuất hiện nào không thể tránh khỏi, cho dù đó là một loạt các generate()
s rằng công việc hoặc lồng nhau spread()
s ...
df %>% gather(loop_number, Q3.2, starts_with("Q3."))