【发布时间】:2020-12-20 19:42:13
【问题描述】:
我有一个数据框(下面的简单示例),其中每个用户填写问卷的次数不同,每次完成问卷都会在数据框中产生一行。在我的简单示例中,用户 A、C 和 D 有 5 天的条目,但用户 B 只有 4 天的条目:
> df
UserId Days_From_First_Use Q1 Q2 Q3
1 A 0 3 2 1
2 A 1 1 0 0
3 A 2 1 1 0
4 A 3 0 2 0
5 A 4 1 1 1
6 B 0 4 8 2
7 B 2 2 2 1
8 B 4 5 6 5
9 B 5 4 5 5
10 C 0 5 7 2
11 C 1 2 2 2
12 C 2 5 5 4
13 C 3 6 5 3
14 C 4 6 6 4
15 D 0 5 3 5
16 D 1 5 3 4
17 D 2 4 2 6
18 D 3 0 0 1
19 D 4 1 1 1
我现在计算每个用户的时间序列波动率如下:
> df <- df %>%
+ group_by(UserId) %>%
+ mutate(across(all_of(c("Q1", "Q2", "Q3")), sd,.names = paste0("Sigma_", "{.col}"))) %>%
+ ungroup()
> df
# A tibble: 19 x 8
UserId Days_From_First_Use Q1 Q2 Q3 Sigma_Q1 Sigma_Q2 Sigma_Q3
<fct> <int> <int> <int> <int> <dbl> <dbl> <dbl>
1 A 0 3 2 1 1.10 0.837 0.548
2 A 1 1 0 0 1.10 0.837 0.548
3 A 2 1 1 0 1.10 0.837 0.548
4 A 3 0 2 0 1.10 0.837 0.548
5 A 4 1 1 1 1.10 0.837 0.548
6 B 0 4 8 2 1.26 2.5 2.06
7 B 2 2 2 1 1.26 2.5 2.06
8 B 4 5 6 5 1.26 2.5 2.06
9 B 5 4 5 5 1.26 2.5 2.06
10 C 0 5 7 2 1.64 1.87 1
11 C 1 2 2 2 1.64 1.87 1
12 C 2 5 5 4 1.64 1.87 1
13 C 3 6 5 3 1.64 1.87 1
14 C 4 6 6 4 1.64 1.87 1
15 D 0 5 3 5 2.35 1.30 2.30
16 D 1 5 3 4 2.35 1.30 2.30
17 D 2 4 2 6 2.35 1.30 2.30
18 D 3 0 0 1 2.35 1.30 2.30
19 D 4 1 1 1 2.35 1.30 2.30
现在是给我带来麻烦的部分:我想计算所有用户的中值 sd,以允许我识别出高于中值和低于中值 sd 的两个用户子集。我不能只计算所有行的中值 sd,因为每个用户的观察次数是不同的。但是,我可以按 Days_From_First_Use 分组 然后计算每天的中位数 sd。由于所有用户都有第 0 天(他们的第一天),因此这一天的中位数 sd 是我想要的值。所以我输入:
> df <- df %>%
+ group_by(UserId) %>%
+ mutate(across(all_of(c("Q1", "Q2", "Q3")), sd,.names = paste0("Sigma_", "{.col}"))) %>%
+ ungroup() %>%
+ group_by(Days_From_First_Use) %>%
+ mutate(across(all_of(paste0("Sigma_", c("Q1", "Q2", "Q3"))), median ,.names = paste0("Median_", "{.col}"))) %>%
+ ungroup()
>
> df
# A tibble: 19 x 11
UserId Days_From_First_Use Q1 Q2 Q3 Sigma_Q1 Sigma_Q2 Sigma_Q3 Median_Sigma_Q1 Median_Sigma_Q2 Median_Sigma_Q3
<fct> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 A 0 3 2 1 1.10 0.837 0.548 1.45 1.59 1.53
2 A 1 1 0 0 1.10 0.837 0.548 1.64 1.30 1
3 A 2 1 1 0 1.10 0.837 0.548 1.45 1.59 1.53
4 A 3 0 2 0 1.10 0.837 0.548 1.64 1.30 1
5 A 4 1 1 1 1.10 0.837 0.548 1.45 1.59 1.53
6 B 0 4 8 2 1.26 2.5 2.06 1.45 1.59 1.53
7 B 2 2 2 1 1.26 2.5 2.06 1.45 1.59 1.53
8 B 4 5 6 5 1.26 2.5 2.06 1.45 1.59 1.53
9 B 5 4 5 5 1.26 2.5 2.06 1.26 2.5 2.06
10 C 0 5 7 2 1.64 1.87 1 1.45 1.59 1.53
11 C 1 2 2 2 1.64 1.87 1 1.64 1.30 1
12 C 2 5 5 4 1.64 1.87 1 1.45 1.59 1.53
13 C 3 6 5 3 1.64 1.87 1 1.64 1.30 1
14 C 4 6 6 4 1.64 1.87 1 1.45 1.59 1.53
15 D 0 5 3 5 2.35 1.30 2.30 1.45 1.59 1.53
16 D 1 5 3 4 2.35 1.30 2.30 1.64 1.30 1
17 D 2 4 2 6 2.35 1.30 2.30 1.45 1.59 1.53
18 D 3 0 0 1 2.35 1.30 2.30 1.64 1.30 1
19 D 4 1 1 1 2.35 1.30 2.30 1.45 1.59 1.53
按照参考方式,整个数据帧的(不正确的)中位数分别为 1.64、1.30 和 1,而正确的中位数为 1.45、1.59 和 1.53。
我现在想用第 0 天的 sd 替换所有中值 sd。一旦这样做,我就可以正确地将数据帧拆分为高 sd 和低 sd 子集。
问题:我如何在这三列中复制正确的第 0 天中位数,然后创建新列,其中包含由用户相对于每个问题的中位数波动率定义的低 sd 和高 sd 子集?
在此致以诚挚的谢意
托马斯·飞利浦
【问题讨论】: