您可以使用来自tidyverse 的dplyr 包来执行此操作。
df <- as_tibble(df)
library(dplyr) # 1.0.0
df %>%
# find only the days in df corresponding to day ranges in patients
filter(day %in% c(seq(patients[1, 3], patients[1, 4], by = "days"),
seq(patients[2, 3], patients[2, 4], by = "days"),
seq(patients[3, 3], patients[3, 4], by = "days"),
seq(patients[4, 3], patients[4, 4], by = "days"))) %>%
# add id column
mutate(id = ifelse(day %in% seq(patients[1, 3], patients[1, 4], by = "days"), patients$id[1],
ifelse(day %in% seq(patients[2, 3], patients[2, 4], by = "days"), patients$id[2],
ifelse(day %in% seq(patients[3, 3], patients[3, 4], by = "days"), patients$id[3], patients$id[4])))) %>%
# group by id
group_by(id) %>%
# find mean occuption for each id
summarise(mean_occupation = mean(ocupation))
# A tibble: 3 x 2
id mean_occupation
<dbl> <dbl>
1 1 29.7
2 2 31.7
3 4 32.2
编辑
带有for 的版本会为许多id 循环:
df <- as_tibble(df)
library(dplyr)
# create days vector from patients
days <- list()
for (i in 1:nrow(patients)) {
dates <- seq(patients[i, 3], patients[i, 4], by = "days")
for (j in 1:length(dates)) {
names(dates)[j] <- patients$id[i]
}
days[[i]] <- dates
}
days <- as.Date(unlist(days), origin = "1970-01-01")
# filter df for days
mid <- df %>%
filter(day %in% days)
# create id col (I couldn't do this directly in mutate())
id <- character()
for (i in 1:nrow(mid)) {
id[i] <- names(days)[which(days == mid$day[i])]
}
# bind together and finish
final <- mid %>%
cbind(id) %>% as_tibble() %>%
group_by(id) %>%
summarise(mean_occupation = mean(ocupation))
> final
# A tibble: 3 x 2
id mean_occupation
<chr> <dbl>
1 1 29.7
2 2 31.7
3 4 32.2