我是R的初学者,正在尝试创建一个新列,该列的值由两列中的行的值确定。
我的 Dataframe 看起来像这样:df <- data.frame(subjectid = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3), subj_day = c("1_1","1_1","1_1","1_2","1_2","2_1","2_1","2_1","2_2","2_2","3_1","3_1","3_1","3_2","3_2"), done_meditation = c(0,0,1,1,1,0,1,1,0,0,1,1,1,1,1))
> df
subjectid subj_day done_meditation
1 1 1_1 0
2 1 1_1 0
3 1 1_1 1
4 1 1_2 1
5 1 1_2 1
6 2 2_1 0
7 2 2_1 1
8 2 2_1 1
9 2 2_2 0
10 2 2_2 0
11 3 3_1 1
12 3 3_1 1
13 3 3_1 1
14 3 3_2 1
15 3 3_2 1
这些数据来自一个多天的研究,参与者每天提供多个回答,每行反映一个回答。
subj_day列显示该行中反映的响应时该参与者的参与者编号和研究日期。
'done_meditation'中的值指的是参与者在做出响应时是否在当天完成了冥想。如果在完成冥想后提供了响应,则done_meditation = 1。因此,如果参与者在当天的任何响应之前完成了冥想,则当天所有的done_meditation行都将= 1。
然而,如果他们在完成冥想之前提供一些响应,而在完成冥想之后提供一些响应,则只有一些done_meditation行将= 1。
我需要创建一个列,提供参与者在整个研究中完成的冥想次数。
因此,新的 Dataframe 可能看起来像这样:
> df
subjectid subj_day done_meditation total_meditations
1 1 1_1 0 2
2 1 1_1 0 2
3 1 1_1 1 2
4 1 1_2 1 2
5 1 1_2 1 2
6 2 2_1 0 1
7 2 2_1 1 1
8 2 2_1 1 1
9 2 2_2 0 1
10 2 2_2 0 1
11 3 3_1 1 2
12 3 3_1 1 2
13 3 3_1 1 2
14 3 3_2 1 2
15 3 3_2 1 2
因为参与者2仅在2个研究日中的1天完成了冥想,所以他们在每一行中获得1分。
因为参与者1和3在研究的两天内完成了冥想,所以他们在每一行中获得2分。
知道实际的研究是7天的可能是有用的,所以参与者的total_meditations得分最高可达7。
我试着写了几个循环,但没有成功,也试着在dplyr中使用group_by和mutate函数,但没有成功。
非常感谢提前任何帮助!
**更新:**我想我已经找到了一个有效的解决方案。下面的内容似乎可以完成这项工作。如果有人有更优雅的解决方案,仍然欢迎任何新的建议:)
df2 <- df %>% group_by(subjectid, subj_day) %>%
summarise(meditationCount = sum(done_meditation)) %>%
mutate(meditationCount = ifelse(meditationCount >= 1, 1, 0)) %>%
group_by(subjectid) %>%
summarise(total_meditations = sum(meditationCount))
merged.df <- merge(df,df2, by = "subjectid")
2条答案
按热度按时间gdx19jrr1#
好代码在构造你自己的答案!一些小建议压缩代码:
max
来获得1或0的依赖日,而不是sum
/ifelse
.groups = "drop_last"
让summarise
为您删除subj_day
组,因此无需第二次调用group_by
。magrittr
%>%
管道也可以工作)P.S.在SO you are allowed to answer your own question上,所以如果你对自己的解决方案感到满意,请将其作为答案发布,你可以接受它,给予自己应得的荣誉!
h22fl7wq2#
根据你自己和安迪的回答,我想补充另一个建议:
如果
max()
的结果用每组(subj_day)的响应数n()
进行了归一化,则可以使用mutate()
而不是summarise()
。然后不再需要left_join()
: