我正在跟踪治疗周前后的暴力事件,看看治疗是否对治疗周前后的事件数量有影响。该表按国家/周划分,记录了1989年至2019年期间大多数国家的暴力事件。它与此类似,但总共约为。120个国家和70k行:
Country Year Week Event_Count Treatment
------- ---- ---- ----------- ---------
Angola 1995 33 3 NA
Angola 1995 34 2 NA
Angola 1995 35 3 NA
Angola 1995 36 0 NA
Angola 1995 37 4 1
Angola 1995 38 1 NA
Angola 1995 39 0 NA
Angola 1995 40 2 NA
Angola 1995 41 3 NA
我想找到平均每周事件数,在治疗周周围分成四周间隔(在本例中,第37周用"1"表示)。(治疗栏),直到12周。换句话说,第1周到第4周将是2个事件,因为这是第33周到36周的平均每周事件数。第0周(在本例中是第37周)将是4周。第1至4周(38至41周)为1.5。第5周至第8周(第29至32周)、第5周至第8周(第42至45周)、第9周至第12周(第25至28周)和第9周至第12周(第46至49周)将是各自箱子内的平均每周值。我使用的是回归不连续设计,所以我想对刚刚错过治疗的国家做同样的事情,用"0"表示;在治疗栏。treatment列中的所有其他值均为"&;na&;"。我想写这样的代码:
aggregate(df[row_interval, column_interval], list(df$Country), mean)
但由于我将在同一个国家内观察几个治疗周,并且治疗周定期变化(例如,安哥拉,1995年第37周;阿尔及利亚,1998年第12周,等等),这行不通。理想情况下,我希望将输出用于处理"0"one_answers"1";与治疗周在同一排。例如:
Country Year Week Event_Count Treatment -12to-9 -8to-5 -4to-1 0 1to4 5to8 9to12
------- ---- ---- ----------- --------- ------- ------ ------ - ---- ---- -----
Algeria 2002 14 4 0 3 0.5 1 4 2 5 2
我试图将类似周的输出放在同一列中,而不管接收"0"或"1";接受治疗。例如,治疗后第1至4周的所有值都在"1至4";列。
提前感谢您的帮助!我对stack和r相当陌生,所以我为任何困惑道歉。
我写了更长的数据,总共包含25周。
Country Year Week Event_Count Treatment
<chr> <dbl> <dbl> <dbl> <dbl>
1 Angola 1995 25 3 NA
2 Angola 1995 26 2 NA
3 Angola 1995 27 4 NA
4 Angola 1995 28 1 NA
5 Angola 1995 29 0 NA
6 Angola 1995 30 4 NA
7 Angola 1995 31 1 NA
8 Angola 1995 32 0 NA
9 Angola 1995 33 3 NA
10 Angola 1995 34 2 NA
# ... with 15 more rows
与您的示例相同,第37周有Treatment
。定义函数gola
为,
gola <- function(df) {
idx <- which(!is.na(df$Treatment))
res <- c()
for (i in idx){
trt <- df$Event_Count
x.3 <- mean(trt[(i-12):(i-9)])
x.2 <- mean(trt[(i-8):(i-5)])
x.1 <- mean(trt[(i-4):(i-1)])
x <- trt[i]
x1 <- mean(trt[(i+1):(i+4)])
x2 <- mean(trt[(i+5):(i+8)])
x3 <- mean(trt[(i+9):(i+12)])
res <- rbind(res,c(x.3, x.2, x.1, x, x1, x2, x3))
}
colnames(res) <- c("_12to_9", "_8to_5", "_4to_1", "0", "1to4", "5to8", "9to12")
res <- cbind(df[idx,], res)
return(res)
}
则gola(df)
返回
Country Year Week Event_Count Treatment _12to_9 _8to_5 _4to_1 0 1to4 5to8 9to12
1 Angola 1995 37 4 1 2.5 1.25 2 4 1.5 2 1.75
这是我得到的。我没有你的实际数据。所以,我创建了我自己的样本数据,这将类似于您的。根据你的实际数据,我的想法可能对你有效,也可能不有效。但我觉得这个想法对解决你的案子有好处。关键在于,如何生成子组索引。你有一个基本行,在治疗中有0 1或NA。(在我的例子中,我只使用了1。你需要考虑在治疗中没有任何1或0的情况。)基本上,我想确定行号,我可以用它作为创建子组的标志。当您想要识别这样的行时,您需要考虑行号何时比基行更小/更大。在第一个case_when()中可以看到这一点。第二个case_when()处理生成组号。在此之后,工作似乎相当简单。我希望这对你有所帮助。
group_by(mydf, Country) %>%
mutate(group = 1:n(),
group = case_when(row_number() %in% (which(Treatment == 1) +
(4 * 1:floor(length(group[which(Treatment == 1):n()]) / 4)) + 1) ~
TRUE,
row_number() %in% (which(Treatment == 1) -
(4 * 1:floor(length(group[1:which(Treatment == 1)]) / 4)) - 1) ~
TRUE,
row_number() == which(Treatment == 1) ~ TRUE,
TRUE ~ FALSE),
group = case_when(row_number() < which(Treatment == 1) ~
cumsum(c(T, diff(group) == -1)),
row_number() > which(Treatment == 1) ~
cumsum(c(F, diff(group) == 1)) + as.integer(100),
TRUE ~ as.integer(100))) %>%
group_by(group, .add = TRUE) %>%
summarize(year = first(Year),
week = paste(first(Week), last(Week), sep = "-"),
average = mean(Event_Count, rm.na = TRUE)) %>%
select(-group)
# Country year week average
# <chr> <dbl> <chr> <dbl>
# 1 Argentina 1995 24-24 4
# 2 Argentina 1995 25-28 5
# 3 Argentina 1995 29-32 7.25
# 4 Argentina 1995 33-36 7.75
# 5 Argentina 1995 37-37 8
# 6 Argentina 1995 38-41 3.5
# 7 Argentina 1995 42-45 7.253
# 8 Argentina 1995 46-49 5.25
# 9 Argentina 1995 50-50 9
#10 Brazil 1995 24-24 4
#11 Brazil 1995 25-28 5
#12 Brazil 1995 29-32 6
#13 Brazil 1995 33-36 7.5
#14 Brazil 1995 37-37 7
#15 Brazil 1995 38-41 6.5
#16 Brazil 1995 42-45 4
#17 Brazil 1995 46-49 6.5
#18 Brazil 1995 50-50 10
set.seed(111)
mydf <- data.frame(Country = rep(c("Argentina", "Brazil"), each = 27),
Year = rep(1995, times = 54),
Week = rep(c(24:50), times = 2),
Event_Count = sample.int(n = 10, size = 54, replace = TRUE),
Treatment = rep(c(rep(NA, times = 13), 1, rep(NA, times = 13)), times = 2))