使用dplyr
,我尝试在变量上匹配n
个其他行的行,因此我可以将匹配集提供给summarise()
。到目前为止,我只成功了一个循环。示例数据:
dfraw <- data.frame( id = c(1:20), age = c(30:35, 32:37, 34:41) )
set.seed(1)
df <- dfraw %>%
mutate( var = age + runif(20) - 0.5 ) %>%
arrange( age )
要根据年龄最接近的五场比赛计算var
的z分数,我可以
for ( i in 1:nrow(df) ) {
df$windowedz[i] <- df %>%
arrange( abs( df$age[i] - age) ) %>%
head(n=6) %>% tail(n=5) %>% # 5 closest matches excluding row `i`
summarise( (df$var[i] - mean(var) ) / sd(var) ) %>%
as.numeric
}
有更优雅的方法来实现这一目标吗?如果我使用group_by
,我似乎无法从单个变量(示例中为df$age[i]
)生成匹配组。
编辑:作为示例数据定义的一部分进行澄清的次要更改arrange
,在列windowedz
中插入标量而不是列表的修改循环
编辑:使用包RcppRoll
,我获得了部分成功:
library(RcppRoll)
df <- df %>%
mutate(
mean = roll_mean( var, n = 5, fill = NA ),
sd = roll_sd( var, n = 5, fill = NA ),
roll_z = (var - mean) / sd
)
此解决方案的问题是窗口包含要转换的值。因此,没有等效于head
- tail
机动,从匹配集中删除匹配的行。此外,如果我直接计算roll_z
而不是先计算mean
和sd
,这种方法会产生奇怪的结果。