在 R 中,如何使用列条件按 ID 获取子集
In R, how to get subset by id with column condition
我有以下数据框。
id <- c(1,1,1,2,2,2,3,3,3,4,4,4)
time <- c(1,2,3,1,2,3,1,2,3,1,2,3)
event1 <- c(0,0,1,0,0,1,0,0,0,1,0,0)
event2 <- c(0,1,0,0,0,0,0,1,0,1,0,0)
event3 <- c(0,0,0,0,0,0,0,1,0,1,0,0)
temp<-data.frame(id,time,event1,event2,event3)
id time event1 event2 event3
1 1 1 0 0 0
2 1 2 0 1 0
3 1 3 1 0 0
4 2 1 0 0 0
5 2 2 0 0 0
6 2 3 1 0 0
7 3 1 0 0 0
8 3 2 0 1 1
9 3 3 0 0 0
10 4 1 1 1 1
11 4 2 0 0 0
12 4 3 0 0 0
如果该事件发生(事件 = 1),我希望获得每个唯一 ID 和 event1、event2、event3 列的子集
所以输出会是这样的:
id event1 event2 event3
1 1 1 1 0
2 2 1 0 0
3 3 0 1 1
4 4 1 1 1
我试图删除重复项并保留唯一 ID,但这给了我错误的输出,因为事件 1 到事件 3 可能不会在时间 = 1 内发生。时间无关紧要。只要该事件发生在三个时间之一内。
如果该事件的 id 中存在 1,我试图通过 id 将 0 替换为 1,但这没有用。
temp %>% group_by(id) %>% mutate(id, event1=ifelse(event1==1,1,event1),
event2 = ifelse(event2==1,1,event2),
event3 =ifelse(event3 ==1,1,event3))
如有任何帮助,我们将不胜感激。
library(tidyverse)
id <- c(1,1,1,2,2,2,3,3,3,4,4,4)
time <- c(1,2,3,1,2,3,1,2,3,1,2,3)
event1 <- as.factor(c(0,0,1,0,0,1,0,0,0,1,0,0))
event2 <-as.factor(c(0,1,0,0,0,0,0,1,0,1,0,0))
event3 <- as.factor(c(0,0,0,0,0,0,0,1,0,1,0,0))
temp<-data.frame(id,time,event1,event2,event3)
temp[,3:5][temp[,3:5]==0] <-NA
temp2 <- as.data.frame(temp%>% group_by(id)%>%
fill(event1,event2,event3,.direction ="downup")
)
temp3 <- temp2[!duplicated(temp2[,'id']),]
temp3[is.na(temp3)] <-0
temp3
这给出了我想要的结果,但我觉得它过于复杂了。
您可以在 dplyr
中使用 summarise()
+ across()
:
library(dplyr)
temp %>%
group_by(id) %>%
summarise(across(contains("event"), sum))
上面的方法计算了每个事件的计数。如果你只想知道事件是否发生,你可以将 sum
部分替换为 max
:
temp %>%
group_by(id) %>%
summarise(across(contains("event"), max))
# A tibble: 4 x 4
id event1 event2 event3
<dbl> <dbl> <dbl> <dbl>
1 1 1 1 0
2 2 1 0 0
3 3 0 1 1
4 4 1 1 1
其他选择
# 1
across(contains("event"), ~ +any(.x == 1))
# 2
across(contains("event"), ~ +(sum(.x) > 0))
(提示: +
将逻辑整数转换为二进制整数)
这是一个可能的 data.table
选项:
library(data.table)
dt <- as.data.table(temp)
dt[, lapply(.SD, max, na.rm = TRUE), by=.(id), .SDcols=patterns("event")]
或者可以使用来自基数 R 的 aggregate
:
aggregate(cbind(event1, event2, event3) ~ id, data = temp, max, na.rm = TRUE)
或 collapse
包:
library(collapse)
collap(temp, event1 + event2 + event3 ~ id, fmax)
输出
id event1 event2 event3
1: 1 1 1 0
2: 2 1 0 0
3: 3 0 1 1
4: 4 1 1 1
我有以下数据框。
id <- c(1,1,1,2,2,2,3,3,3,4,4,4)
time <- c(1,2,3,1,2,3,1,2,3,1,2,3)
event1 <- c(0,0,1,0,0,1,0,0,0,1,0,0)
event2 <- c(0,1,0,0,0,0,0,1,0,1,0,0)
event3 <- c(0,0,0,0,0,0,0,1,0,1,0,0)
temp<-data.frame(id,time,event1,event2,event3)
id time event1 event2 event3
1 1 1 0 0 0
2 1 2 0 1 0
3 1 3 1 0 0
4 2 1 0 0 0
5 2 2 0 0 0
6 2 3 1 0 0
7 3 1 0 0 0
8 3 2 0 1 1
9 3 3 0 0 0
10 4 1 1 1 1
11 4 2 0 0 0
12 4 3 0 0 0
如果该事件发生(事件 = 1),我希望获得每个唯一 ID 和 event1、event2、event3 列的子集
所以输出会是这样的:
id event1 event2 event3
1 1 1 1 0
2 2 1 0 0
3 3 0 1 1
4 4 1 1 1
我试图删除重复项并保留唯一 ID,但这给了我错误的输出,因为事件 1 到事件 3 可能不会在时间 = 1 内发生。时间无关紧要。只要该事件发生在三个时间之一内。
如果该事件的 id 中存在 1,我试图通过 id 将 0 替换为 1,但这没有用。
temp %>% group_by(id) %>% mutate(id, event1=ifelse(event1==1,1,event1),
event2 = ifelse(event2==1,1,event2),
event3 =ifelse(event3 ==1,1,event3))
如有任何帮助,我们将不胜感激。
library(tidyverse)
id <- c(1,1,1,2,2,2,3,3,3,4,4,4)
time <- c(1,2,3,1,2,3,1,2,3,1,2,3)
event1 <- as.factor(c(0,0,1,0,0,1,0,0,0,1,0,0))
event2 <-as.factor(c(0,1,0,0,0,0,0,1,0,1,0,0))
event3 <- as.factor(c(0,0,0,0,0,0,0,1,0,1,0,0))
temp<-data.frame(id,time,event1,event2,event3)
temp[,3:5][temp[,3:5]==0] <-NA
temp2 <- as.data.frame(temp%>% group_by(id)%>%
fill(event1,event2,event3,.direction ="downup")
)
temp3 <- temp2[!duplicated(temp2[,'id']),]
temp3[is.na(temp3)] <-0
temp3
这给出了我想要的结果,但我觉得它过于复杂了。
您可以在 dplyr
中使用 summarise()
+ across()
:
library(dplyr)
temp %>%
group_by(id) %>%
summarise(across(contains("event"), sum))
上面的方法计算了每个事件的计数。如果你只想知道事件是否发生,你可以将 sum
部分替换为 max
:
temp %>%
group_by(id) %>%
summarise(across(contains("event"), max))
# A tibble: 4 x 4
id event1 event2 event3
<dbl> <dbl> <dbl> <dbl>
1 1 1 1 0
2 2 1 0 0
3 3 0 1 1
4 4 1 1 1
其他选择
# 1
across(contains("event"), ~ +any(.x == 1))
# 2
across(contains("event"), ~ +(sum(.x) > 0))
(提示: +
将逻辑整数转换为二进制整数)
这是一个可能的 data.table
选项:
library(data.table)
dt <- as.data.table(temp)
dt[, lapply(.SD, max, na.rm = TRUE), by=.(id), .SDcols=patterns("event")]
或者可以使用来自基数 R 的 aggregate
:
aggregate(cbind(event1, event2, event3) ~ id, data = temp, max, na.rm = TRUE)
或 collapse
包:
library(collapse)
collap(temp, event1 + event2 + event3 ~ id, fmax)
输出
id event1 event2 event3
1: 1 1 1 0
2: 2 1 0 0
3: 3 0 1 1
4: 4 1 1 1