【发布时间】:2014-11-13 13:19:03
【问题描述】:
我有来自在线调查的数据,其中受访者会回答 1-3 次循环问题。调查软件 (Qualtrics) 将这些数据记录在多个列中——也就是说,调查中的 Q3.2 将有列 Q3.2.1.、Q3.2.2. 和 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
...
我想将所有 QN.N* 列组合成整齐的单独 QN.N 列,最终得到如下结果:
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 库具有 gather() 函数,非常适合组合 一个 列集:
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
结果数据框有 30 行,正如预期的那样(10 个人,每个人 3 个循环)。但是,收集第二组列不能正常工作——它成功地生成了两个组合列 Q3.2 和 Q3.3,但最终得到 90 行而不是 30 行(所有 10 个人的组合,Q3.2 的 3 个循环, 和 Q3.3 的 3 个循环;实际数据中每组列的组合会大幅增加):
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
有没有办法像这样使用对gather() 的多次调用,像这样组合列的小子集,同时保持正确的行数?
【问题讨论】:
-
df %>% gather(loop_number, Q3.2, starts_with("Q3."))有什么问题 -
这让我得到一个包含 60 行的合并列。我想如果我随后对
seperate()进行某种调用以将Q3.3(及更高版本)值划分到它们自己的列中,那可能会起作用。但这似乎仍然是一个非常迂回的hacky解决方案...... -
使用
spread我现在正在研究解决方案: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) -
哦,这对这两个变量非常有效。不过,我很好奇它是否具有可扩展性——在我的真实数据中,我得到了 Q3.2-Q3.30,因此它需要大量单独调用
spread()。尽管多次调用似乎是不可避免的,但无论是一组有效的generate()s 还是嵌套的spread()s...
标签: r reshape dplyr qualtrics tidyr