Background
我有这个R
数据帧,d
.它看起来像这样:
d <- data.frame(ID = c("a","a","a","a","a","a","a","b","b","b","b"),
treatment = c(0,1,0,0,0,1,0,1,0,0,0),
event = c(0,0,1,1,1,1,1,0,1,1,1),
service_date = as.Date(c("2011-01-01",
"2011-08-21",
"2011-12-23",
"2012-02-23",
"2013-09-14",
"2013-04-07",
"2014-10-14",
"2013-01-01",
"2013-12-12",
"2014-06-17",
"2015-09-29")),
stringsAsFactors=FALSE)
里面有两个人(ID
a和b),还有一些关于他们是否收到treatment
的信息,他们是否有event
,以及当这些事情发生时service_date
。
问题和我正在寻找什么
我的目标是弄清楚event==1
的人在第一次treatment==1
后的第n年平均有多少人。这是我想要的结果,以及治疗后第一年我将如何手工完成:
对于每个
ID
,找到treatment
等于1
的第一个service_date
。对于ID
=a,这就是2011-08-21
.对于"第一个
treatment
日期",向前计数 365 天。对于ID
=a,那将是2012-08-21
.这为您提供了"第一treatment
后的第一年"的间隔。在该间隔内,计算/统计
event==1
次数。对于ID
=a 的第一年(所以在2011-08-21
到2012-08-21
之间),这是2次:一次在2011-12-23
上,另一次在2012-02-23
上。对其他
ID
重复步骤 1、2 和 3(在本例中仅为 b)并获取它们的计数。对于ID
=b',这将只是一个事件:在2013-01-01
年到一年后的2014-01-01
年之间,他们只有一个事件,在2013-12-12
上。将计数相加并除以
ID
的数量以获得平均值。在这里,这将是(2 个事件 + 1 个事件)/2 人 ==1.5 个事件,平均在第一次治疗后的第 1 年
所以换句话说,这是一个应该吐出一个数字的计算:
> d %>% ... etc etc ...
# A tibble: 1 x 1
mean
<dbl>
1 1.5
理想情况下,我希望能够在第一次treatment
后修改代码以定义不同的间隔。就像第 2 年可能是"第一个treatment
+365 和第一个treatment
+730 之间的时间"。
我尝试过什么
我正在弄乱一些 R 代码来尝试这样做。从概念上讲,我的方法包括以下内容:
首先,要
mutate
新列year_interval
,请使用difftime
函数定义R
应为每个ID
的事件计数的间隔。接下来,
mutate
另一列interval_event_count
进行实际计数。使用
mean
完成操作。
当然,这可能不是唯一有效的方法(它甚至可能根本不有效)。
到目前为止,我已经这样做了,但它给了我一个关于difftime
的错误:
d <- d %>%
group_by(ID) %>%
arrange(service_date) %>%
mutate(
year_interval = difftime(min(treatment==1), min(treatment==1)+365, units = "days"),
interval_event_count = tally(year_interval)) %>%
ungroup() %>%
mean(interval_event_count)
Error in `mutate_cols()`:
! Problem with `mutate()` column `year_interval`.
i `year_interval = difftime(min(treatment == 1), min(treatment == 1) + 365, units = "days")`.
x 'origin' must be supplied
i The error occurred in group 1: ID = "a".
Caused by error in `as.POSIXct.numeric()`:
! 'origin' must be supplied
这是一个逐步执行您在问题中提供的内容dplyr
:
d %>%
group_by(ID) %>%
mutate(x = first(service_date[treatment==1]),
y = first(service_date[treatment==1])+365+1
) %>%
rowwise() %>%
mutate(z = ifelse(between(service_date, x, y), 1, 0)) %>%
group_by(ID) %>%
summarise(count = (sum(z[event==1])+1)/2)
ID count
<chr> <dbl>
1 a 1.5
2 b 1
这是一个带有dplyr
的选项 - 按"ID"和"service_date"分组,获取"治疗"中第一次出现的 1 的索引match
,要获得"service_date_min",添加 365 以返回"service_date_max",然后也按"service_date_min"分组,得到"治疗"的sum
(如果它是二进制的, sum 返回 1 的计数),然后在我们删除最后一组时得到 'n' 的mean
,即service_date_min
library(dplyr)
d %>%
arrange(ID, service_date) %>%
group_by(ID) %>%
filter(cumsum(treatment == 1) > 0) %>%
mutate(service_date_min = service_date[match(1, treatment)],
service_date_max = service_date_min + 365 +1,
i1 = service_date > service_date_min &
service_date < service_date_max & event == 1) %>%
summarise(n = sum(i1)) %>%
mutate(n = case_when(n ==1 ~ 1, TRUE ~ sum(n)/n))
-输出
# A tibble: 2 × 2
ID n
<chr> <dbl>
1 a 1.5
2 b 1
也许只是构建一个小函数来执行计算,并且还需要参数s
和e
f <- function(tx,ev,d,s=0,e=365) {
tx1 = min(d[tx==1])
interval = c(tx1+s,tx1+e)
sum(ev[which(d>=interval[1] & d<=interval[2])])
}
用法:
d %>% group_by(ID) %>%
summarize(ev = f(treatment, event, service_date)) %>%
summarize(result = mean(ev))
输出:
# A tibble: 1 x 1
result
<dbl>
1 1.5
如果要获取其他值,只需更改默认s
并e
,如下所示:
d %>% group_by(ID) %>%
summarize(ev = f(treatment, event, service_date,s=365, e=730)) %>%
summarize(result = mean(ev))
更好的是,做一个包装函数,比如get_events
,像这样:
get_events <- function(dt,s=0, e=365) {
group_by(dt,ID) %>%
summarize(ev = f(treatment, event, service_date, s=s, e=e)) %>%
summarize(result = mean(ev))
}
并像这样称呼它:
get_events(d)
get_events(d,365,730),
get_events(d,e=730)
当然,如果您正在寻找速度,请不要使用group_by()/summarize()
。相反,将d
设置为 data.table,然后像这样运行:
library(data.table)
setDT(d)[, f(treatment,event,service_date), by=ID][, mean(V1)]
Ouptut:
[1] 1.5