r语言 - 按间隔查找列中的平均值

  • 本文关键字:平均值 查找 r语言 r mean
  • 更新时间 :
  • 英文 :


我正在跟踪治疗周前后的暴力事件,看看治疗是否对治疗周前后的事件数量有影响。该表按国家/周划分,记录了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))

最新更新