我正在尝试使用dplyr
找到一种更简单的方法来计算数据框中变量(由列表示)的变化。我的玩具数据集是这样的
structure(list(CAR = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 1L,
2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L), .Label = c("a",
"b", "c", "d", "e", "f"), class = "factor"), TIME = c(0L, 0L,
0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L
), VAR = c(20L, 30L, 40L, 50L, 60L, 70L, 30L, 40L, 50L, 60L,
70L, 80L, 40L, 50L, 60L, 70L, 80L, 90L)), .Names = c("CAR", "TIME",
"VAR"), class = "data.frame", row.names = c(NA, -18L))
看起来像
CAR TIME VAR
1 a 0 20
2 b 0 30
3 c 0 40
4 d 0 50
5 e 0 60
6 f 0 70
7 a 1 30
8 b 1 40
9 c 1 50
10 d 1 60
11 e 1 70
12 f 1 80
13 a 2 40
14 b 2 50
15 c 2 60
16 d 2 70
17 e 2 80
18 f 2 90
我正在尝试计算VAR
之间的变化TIME
等于0
和其他时间,例如,每个1,2
CAR
。
这就是我所做的,这似乎是一种非常复杂的方式,首先我得到VAR
的值TIME
等于0
library(dplyr)
X <- local_test %>% filter(TIME == 0) %>% group_by(CAR) %>% mutate(baseline_VAR = VAR)
X
看起来像
Source: local data frame [6 x 4]
Groups: CAR
CAR TIME VAR baseline_VAR
1 a 0 20 20
2 b 0 30 30
3 c 0 40 40
4 d 0 50 50
5 e 0 60 60
6 f 0 70 70
然后,我使用原始数据框left_join
local_test
Y <- left_join(local_test, X, by = c("CAR"))
Y
看起来像
CAR TIME.x VAR.x TIME.y VAR.y baseline_VAR
1 a 0 20 0 20 20
2 b 0 30 0 30 30
3 c 0 40 0 40 40
4 d 0 50 0 50 50
5 e 0 60 0 60 60
6 f 0 70 0 70 70
7 a 1 30 0 20 20
8 b 1 40 0 30 30
9 c 1 50 0 40 40
10 d 1 60 0 50 50
11 e 1 70 0 60 60
12 f 1 80 0 70 70
13 a 2 40 0 20 20
14 b 2 50 0 30 30
15 c 2 60 0 40 40
16 d 2 70 0 50 50
17 e 2 80 0 60 60
18 f 2 90 0 70 70
最后,我在Y
中添加了一列,用于计算VAR
之间TIME
的变化CAR
Y %>% group_by(CAR) %>% mutate(change_VAR = VAR.x - baseline_VAR)
最终Y
看起来像
Source: local data frame [18 x 7]
Groups: CAR
CAR TIME.x VAR.x TIME.y VAR.y baseline_VAR change_VAR
1 a 0 20 0 20 20 0
2 b 0 30 0 30 30 0
3 c 0 40 0 40 40 0
4 d 0 50 0 50 50 0
5 e 0 60 0 60 60 0
6 f 0 70 0 70 70 0
7 a 1 30 0 20 20 10
8 b 1 40 0 30 30 10
9 c 1 50 0 40 40 10
10 d 1 60 0 50 50 10
11 e 1 70 0 60 60 10
12 f 1 80 0 70 70 10
13 a 2 40 0 20 20 20
14 b 2 50 0 30 30 20
15 c 2 60 0 40 40 20
16 d 2 70 0 50 50 20
17 e 2 80 0 60 60 20
18 f 2 90 0 70 70 20
这似乎是一项额外的工作,在原始数据框中添加了额外的列。我需要重复对大数据帧执行此操作。是否有更简单(一步)的方式来计算change_VAR
?
谢谢!
答案 0 :(得分:4)
这可以通过采用“VAR&#39; VAR”的区别来实现。使用min
&#39; VAR&#39;按&#39; CAR&#39;分组。
local_test %>%
group_by(CAR) %>%
mutate(change_VAR= VAR- min(VAR))
或者如果&#39; VAR&#39;的基值?是时候&#39;时间&#39;是0(假设每个组没有重复的&#39; TIME&#39;)我们将“&#39; VAR&#39;对于TIME 0并获得差异。
local_test %>%
group_by(CAR) %>%
mutate(change_VAR= VAR- VAR[TIME==0])
答案 1 :(得分:3)
group_by(DF, CAR) %>%
arrange(CAR, TIME) %>%
mutate(change_VAR = VAR-VAR[1]) %>%
ungroup() %>%
arrange(TIME, CAR)
我做了一点安排akrun,但我不假设数据是在前面正确订购的。安排也确保最早的观察位于每组的第1位。
编辑: 如果你对这种事感兴趣。这是我和Akrun的答案之间的速度比较。 (简答,和Akrun一起去)
microbenchmark(
akrun1 = DF %>%
group_by(CAR) %>%
mutate(change_VAR= VAR- min(VAR)),
akrun2 = DF %>%
group_by(CAR) %>%
mutate(change_VAR= VAR- VAR[TIME==0]),
Benjamin = group_by(DF, CAR) %>%
arrange(CAR, TIME) %>%
mutate(change_VAR = VAR-VAR[1]) %>%
ungroup() %>%
arrange(TIME, CAR))
unit: microseconds
expr min lq mean median uq max neval cld
akrun1 887.360 903.1950 975.6354 930.467 954.5125 3246.223 100 a
akrun2 888.240 901.1425 947.5220 913.899 952.7530 3002.536 100 a
Benjamin 1584.697 1604.7835 1720.8034 1662.993 1692.1705 3765.561 100 b