给定一个数据集,如:
set.seed(134)
df<- data.frame(ID= rep(LETTERS[1:5], each=2),
condition=rep(0:1, 5),
value=rpois(10, 3)
)
df
ID condition value
1 A 0 2
2 A 1 3
3 B 0 5
4 B 1 2
5 C 0 3
6 C 1 1
7 D 0 2
8 D 1 4
9 E 0 1
10 E 1 5
对于每个ID,当condition == 0的值小于condition == 1的值时,我想保留两个观察值。当condition == 0的值大于condition == 1时,我想只保留condition == 0的行。
返回的子集应为:
ID condition value
1 A 0 2
2 A 1 3
3 B 0 5
5 C 0 3
7 D 0 2
8 D 1 4
9 E 0 1
10 E 1 5
使用dplyr的第一步是:
df %>% group_by(ID) %>%
但不确定从哪里开始。
答案 0 :(得分:1)
这可能不是最简单的方法,但应该按照您的意愿工作。
library(reshape2)
df %>%
dcast(ID ~ condition, value.var = 'value') %>% # cast to wide format
mutate(`1` = ifelse(`1` > `0`, `1`, NA)) %>% # turn 0>1 values as NA
melt('ID') %>% # melt as long format
arrange(ID) %>% # sort by ID
filter(complete.cases(.)) # remove NA rows
输出:
ID variable value
1 A 0 2
2 A 1 3
3 B 0 5
4 C 0 3
5 D 0 2
6 D 1 4
7 E 0 1
8 E 1 5
答案 1 :(得分:1)
您始终需要每组中第一行的值。如果每个组中的第二行大于第一行,则只需要该值。
这有效:
df %>%
group_by(ID) %>%
filter(row_number() == 1 | value > lag(value))
编辑:正如@alistaire所指出的,这种方法取决于特定的顺序,这可能是一个好主意,保证如下:
df %>%
arrange(ID, condition) %>%
group_by(ID) %>%
filter(row_number() == 1 | value > lag(value))
答案 2 :(得分:1)
字面翻译,
library(dplyr)
set.seed(134)
df <- data.frame(ID = rep(LETTERS[1:5], each = 2),
condition = rep(0:1, 5),
value = rpois(10, 3))
df %>% group_by(ID) %>%
filter(condition == 0 |
(condition == 1 & value > value[condition == 0]))
#> # A tibble: 8 x 3
#> # Groups: ID [5]
#> ID condition value
#> <fct> <int> <int>
#> 1 A 0 2
#> 2 A 1 3
#> 3 B 0 5
#> 4 C 0 3
#> 5 D 0 2
#> 6 D 1 4
#> 7 E 0 1
#> 8 E 1 5
这取决于每个小组对condition == 0
进行单一观察,但应该相当稳健。