英文:
Calculating score change at two or more time point
问题
我有一个非常简单的问题:想象一下一个认知测试,其中有6个项目,每个项目都在0-10分的标度上分别评分。
现在假设有5名患者在一天中的三个(或更多)不同时间进行了这个测试。
df <- tibble(
id = rep(1:5, each = 3),
time = rep(c("morning", "evening", "night"), each = 1, times = 5),
i1 = round(runif(15, 0, 10)),
i2 = round(runif(15, 0, 10)),
i3 = round(runif(15, 0, 10)),
i4 = round(runif(15, 0, 10)),
i5 = round(runif(15, 0, 10)),
i6 = round(runif(15, 0, 10))
)
现在,我该如何计算每个患者在不同时间段内每个个别项目得分的变化?欢迎使用tidyverse
方法。
P.S:输出最好是这样的:
df <- tibble(
id = rep(1:5, each = 3),
time = rep(c("morning", "evening", "night"), each = 1, times = 5),
i1 = round(runif(15, 0, 10)),
i2 = round(runif(15, 0, 10)),
i3 = round(runif(15, 0, 10)),
i4 = round(runif(15, 0, 10)),
i5 = round(runif(15, 0, 10)),
i6 = round(runif(15, 0, 10)),
diff_morning_evening = rep(NA, 15),
diff_morning_night = rep(NA, 15),
diff_evening_night = rep(NA, 15),
)
英文:
I have a very simple question: Imagine a cognitive test with 6 items, each of which is scored separately on a 0-10 scale
now let's say 5 patients have taken this test at three (or more) different time of the day.
df <- tibble(
id = rep(1:5, each = 3),
time = rep(c("morning", "evening", "night"), each = 1, times = 5),
i1 = round(runif(15, 0, 10)),
i2 = round(runif(15, 0, 10)),
i3 = round(runif(15, 0, 10)),
i4 = round(runif(15, 0, 10)),
i5 = round(runif(15, 0, 10)),
i6 = round(runif(15, 0, 10))
)
Now, how can I calculate the changes in the score of each individual item for every patient between different times of the day?
tidyverse
approaches are highly appreciated.
P.S: the output should be preferably something like this:
df <- tibble(
id = rep(1:5, each = 3),
time = rep(c("morning", "evening", "night"), each = 1, times = 5),
i1 = round(runif(15, 0, 10)),
i2 = round(runif(15, 0, 10)),
i3 = round(runif(15, 0, 10)),
i4 = round(runif(15, 0, 10)),
i5 = round(runif(15, 0, 10)),
i6 = round(runif(15, 0, 10)),
diff_morning_evening = rep(NA, 15),
diff_morning_night = rep(NA, 15),
diff_evening_night = rep(NA, 15),
)
答案1
得分: 3
以下是翻译好的内容:
计算变化的方法:
- 第1行:早上 - 晚上
- 第2行:早上 - 傍晚
- 第3行:傍晚 - 晚上
df %>%
group_by(id) %>%
mutate(across(i1:i6, ~ ifelse(is.na(.x - lag(.x)),
lead(.x, 2) - .x, .x - lag(.x)),
.names="\\{.col}_chg")) %>%
ungroup()
# 一个 tibble: 15 × 14
id time i1 i2 i3 i4 i5 i6 i1_chg i2_chg i3_chg i4_chg
<int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 早上 1 2 4 9 5 6 7 -1 1 -8
2 1 傍晚 5 0 4 8 9 4 4 -2 0 -1
3 1 晚上 8 1 5 1 4 5 3 1 1 -7
4 2 早上 7 7 4 3 2 9 -5 -1 4 5
5 2 傍晚 8 9 1 2 4 5 1 2 -3 -1
6 2 晚上 2 6 8 8 10 2 -6 -3 7 6
7 3 早上 9 6 6 1 5 5 -8 -1 2 0
8 3 傍晚 3 2 8 1 3 10 -6 -4 2 0
9 3 晚上 1 5 8 1 3 3 -2 3 0 0
10 4 早上 7 2 9 1 5 8 1 1 -6 0
11 4 傍晚 3 5 9 5 6 3 -4 3 0 4
12 4 晚上 8 3 3 1 3 2 5 -2 -6 -4
13 5 早上 4 1 3 7 1 0 4 6 4 2
14 5 傍晚 7 2 7 7 5 2 3 1 4 0
15 5 晚上 8 7 7 9 8 4 1 5 0 2
# … 还有 2 个变量:i5_chg 和 i6_chg
特殊行求和方法:
df %>%
group_by(id) %>%
summarize(across(i1:i6, ~
.x[which(time == "早上")] + .x[which(time == "晚上")]))
# 一个 tibble: 5 × 7
id i1 i2 i3 i4 i5 i6
<int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 9 3 9 10 9 11
2 2 9 13 12 11 12 11
3 3 10 11 14 2 8 8
4 4 15 5 12 2 8 10
5 5 12 8 10 16 9 4
注意:代码部分未进行翻译,仅提供了翻译好的内容。
英文:
An approach calculating the changes in a compact way:
- 1st row: morning - night
- 2nd row: morning - evening
- 3rd row: evening - night
df %>%
group_by(id) %>%
mutate(across(i1:i6, ~ ifelse(is.na(.x - lag(.x)),
lead(.x, 2) - .x, .x - lag(.x)),
.names="{.col}_chg")) %>%
ungroup()
# A tibble: 15 × 14
id time i1 i2 i3 i4 i5 i6 i1_chg i2_chg i3_chg i4_chg
<int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 morning 1 2 4 9 5 6 7 -1 1 -8
2 1 evening 5 0 4 8 9 4 4 -2 0 -1
3 1 night 8 1 5 1 4 5 3 1 1 -7
4 2 morning 7 7 4 3 2 9 -5 -1 4 5
5 2 evening 8 9 1 2 4 5 1 2 -3 -1
6 2 night 2 6 8 8 10 2 -6 -3 7 6
7 3 morning 9 6 6 1 5 5 -8 -1 2 0
8 3 evening 3 2 8 1 3 10 -6 -4 2 0
9 3 night 1 5 8 1 3 3 -2 3 0 0
10 4 morning 7 2 9 1 5 8 1 1 -6 0
11 4 evening 3 5 9 5 6 3 -4 3 0 4
12 4 night 8 3 3 1 3 2 5 -2 -6 -4
13 5 morning 4 1 3 7 1 0 4 6 4 2
14 5 evening 7 2 7 7 5 2 3 1 4 0
15 5 night 8 7 7 9 8 4 1 5 0 2
# … with 2 more variables: i5_chg <dbl>, i6_chg <dbl>
Summing special rows approach
df %>%
group_by(id) %>%
summarize(across(i1:i6, ~
.x[which(time == "morning")] + .x[which(time == "night")]))
# A tibble: 5 × 7
id i1 i2 i3 i4 i5 i6
<int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 9 3 9 10 9 11
2 2 9 13 12 11 12 11
3 3 10 11 14 2 8 8
4 4 15 5 12 2 8 10
5 5 12 8 10 16 9 4
答案2
得分: 3
你可以使用combn
生成所有的两两组合,并对每个组合应用diff
函数来计算更改,设置FUN = diff
。
library(tidyverse)
df %>%
group_by(id) %>%
summarise(DIFF = combn(time, 2, paste, collapse = '_'),
across(i1:i6, ~ combn(.x, 2, diff)), .groups = 'drop')
# # A tibble: 15 × 8
# id DIFF i1 i2 i3 i4 i5 i6
# <int> <chr[1d]> <dbl[1d]> <dbl[1d]> <dbl[1d]> <dbl[1d]> <dbl[1d]> <dbl[1d]>
# 1 1 morning_evening 1 -2 0 5 1 3
# 2 1 morning_night -2 5 1 3 -2 -1
# 3 1 evening_night -3 7 1 -2 -3 -4
# 4 2 morning_evening 1 5 -2 -3 5 7
# 5 2 morning_night 2 -1 6 2 -2 1
# 6 2 evening_night 1 -6 8 5 -7 -6
# ...
如果你想要宽格式的输出,请将上述代码传递给tidyr::pivot_wider()
:
... %>%
pivot_wider(names_from = DIFF, values_from = i1:i6, names_prefix = 'diff_')
# # A tibble: 5 × 19
# id i1_diff_morning_evening i1_diff_morning_night i1_diff_evening_night i2_diff_morning_evening i2_diff_morning_night i2_diff_evening_night
# <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 1 -2 -3 -2 5 7
# 2 2 1 2 1 5 -1 -6
# 3 3 2 -1 -3 5 -1 -6
# 4 4 1 2 1 -2 -4 -2
# 5 5 6 7 1 1 0 -1
#
# … with 12 more variables:
# i3_diff_morning_evening <dbl>, i3_diff_morning_night <dbl>, i3_diff_evening_night <dbl>,
# i4_diff_morning_evening <dbl>, i4_diff_morning_night <dbl>, i4_diff_evening_night <dbl>,
# i5_diff_morning_evening <dbl>, i5_diff_morning_night <dbl>, i5_diff_evening_night <dbl>,
# i6_diff_morning_evening <dbl>, i6_diff_morning_night <dbl>, i6_diff_evening_night <dbl>
英文:
You can use combn
to generate all combinations of 2 times, and apply diff
to each combination to calculate the change by setting FUN = diff
.
library(tidyverse)
df %>%
group_by(id) %>%
summarise(DIFF = combn(time, 2, paste, collapse = '_'),
across(i1:i6, ~ combn(.x, 2, diff)), .groups = 'drop')
# # A tibble: 15 × 8
# id DIFF i1 i2 i3 i4 i5 i6
# <int> <chr[1d]> <dbl[1d]> <dbl[1d]> <dbl[1d]> <dbl[1d]> <dbl[1d]> <dbl[1d]>
# 1 1 morning_evening 1 -2 0 5 1 3
# 2 1 morning_night -2 5 1 3 -2 -1
# 3 1 evening_night -3 7 1 -2 -3 -4
# 4 2 morning_evening 1 5 -2 -3 5 7
# 5 2 morning_night 2 -1 6 2 -2 1
# 6 2 evening_night 1 -6 8 5 -7 -6
# ...
If you want a wide-format output, pass the above code to tidyr::pivot_wider()
:
... %>%
pivot_wider(names_from = DIFF, values_from = i1:i6, names_prefix = 'diff_')
# # A tibble: 5 × 19
# id i1_diff_morning_evening i1_diff_morning_night i1_diff_evening_night i2_diff_morning_evening i2_diff_morning_night i2_diff_evening_night
# <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 1 -2 -3 -2 5 7
# 2 2 1 2 1 5 -1 -6
# 3 3 2 -1 -3 5 -1 -6
# 4 4 1 2 1 -2 -4 -2
# 5 5 6 7 1 1 0 -1
#
# … with 12 more variables:
# i3_diff_morning_evening <dbl>, i3_diff_morning_night <dbl>, i3_diff_evening_night <dbl>,
# i4_diff_morning_evening <dbl>, i4_diff_morning_night <dbl>, i4_diff_evening_night <dbl>,
# i5_diff_morning_evening <dbl>, i5_diff_morning_night <dbl>, i5_diff_evening_night <dbl>,
# i6_diff_morning_evening <dbl>, i6_diff_morning_night <dbl>, i6_diff_evening_night <dbl>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论