使用 r 中的规格切片长数据
Slice long data with specifications in r
如果我有这样的数据
id<-c(1,1,1,1,2,2,2,3,3,3,3,4,4,4,5,5,5,5,5)
age<-c(12,14,15,16,12,13,14,14,16,17,19,12,13,14,15,16,18,20,21)
grade<-c('B','C','C','A','D','B','B','A','B','A','A','D','F','B','F','F','B','B','C')
data<-data.frame(id,age,grade)
假设 ID 是每个学生 (1:5) 在不同时间测量他们的成绩,我想看看他们在获得第一个 B 后在什么年龄发生了随后的成绩变化。
对于学生 1,他在 12 岁时获得了 B,s/he 在 14 岁时获得了 C,这很简单。然而,对于学生 5,s/he 在 18 岁时首次获得 B,然后 s/he 在 20 岁时再次获得 B,因此第一次成绩变化发生在 21 岁,即 C。
我认为 slice 是最好的选择。
data %>% group_by(id,grade) %>% slice(which.min(age))
但我不确定如何包含接下来的几行以捕获 B 变成另一个年级(不再是 B)的“年龄”。
一个data.table
选项
setDT(data)[, .SD[first(which((1:.N) > first(which(grade == "B")) &
grade != "B"))], id]
给予
id age grade
1: 1 14 C
2: 3 17 A
3: 5 21 C
这可能是使用 dplyr 的滞后函数的解决方案:
data %>%
group_by(id) %>%
arrange(id, age, grade) %>%
mutate(tag = ifelse(grade == lag(grade), "Same Grade", "Different Grade"))
选项dplyr
library(dplyr)
data %>%
group_by(id) %>%
filter(!(duplicated(grade) & grade == 'B') ) %>%
slice(match('B', grade) + 1)
# A tibble: 3 x 3
# Groups: id [3]
# id age grade
# <dbl> <dbl> <chr>
#1 1 14 C
#2 3 17 A
#3 5 21 C
如果我有这样的数据
id<-c(1,1,1,1,2,2,2,3,3,3,3,4,4,4,5,5,5,5,5)
age<-c(12,14,15,16,12,13,14,14,16,17,19,12,13,14,15,16,18,20,21)
grade<-c('B','C','C','A','D','B','B','A','B','A','A','D','F','B','F','F','B','B','C')
data<-data.frame(id,age,grade)
假设 ID 是每个学生 (1:5) 在不同时间测量他们的成绩,我想看看他们在获得第一个 B 后在什么年龄发生了随后的成绩变化。 对于学生 1,他在 12 岁时获得了 B,s/he 在 14 岁时获得了 C,这很简单。然而,对于学生 5,s/he 在 18 岁时首次获得 B,然后 s/he 在 20 岁时再次获得 B,因此第一次成绩变化发生在 21 岁,即 C。
我认为 slice 是最好的选择。
data %>% group_by(id,grade) %>% slice(which.min(age))
但我不确定如何包含接下来的几行以捕获 B 变成另一个年级(不再是 B)的“年龄”。
一个data.table
选项
setDT(data)[, .SD[first(which((1:.N) > first(which(grade == "B")) &
grade != "B"))], id]
给予
id age grade
1: 1 14 C
2: 3 17 A
3: 5 21 C
这可能是使用 dplyr 的滞后函数的解决方案:
data %>%
group_by(id) %>%
arrange(id, age, grade) %>%
mutate(tag = ifelse(grade == lag(grade), "Same Grade", "Different Grade"))
选项dplyr
library(dplyr)
data %>%
group_by(id) %>%
filter(!(duplicated(grade) & grade == 'B') ) %>%
slice(match('B', grade) + 1)
# A tibble: 3 x 3
# Groups: id [3]
# id age grade
# <dbl> <dbl> <chr>
#1 1 14 C
#2 3 17 A
#3 5 21 C