问题描述
想象两个数据集。数据集df1是一年中发生某个事件的日期。 Df1还有多个其他列,但是出于这个问题的目的,只有日期很重要。 Df2包含两列,一年中的一天进行一次测量,以及该测量的值。本质上,我想在df1中创建一个新列(“ AVG”),该列是df2中当天的平均值加上前一天的值。例如,df1第2天的AVG为12.5((10 + 15)/ 2)。
以下一些示例数据。
df1 <- structure(list(day = c(2,5,7)),class = "data.frame",row.names = c(NA,-3L))
df2 <- structure(list(day = c(1,2,3,4,6,7,8),value = c(10,15,8,13,20,25,12)),-8L))
以下示例最终产品。
df3 <- structure(list(day = c(2,7),AVG = c(12.5,10,22.5)),-3L))
解决方法
您可以使用base R
在这样的位置附近使用索引进行播放。计算平均值很容易,因为您只希望对两个值进行度量。最后,您可以将结果分配给df1
:
#Detect position
i1 <- which(df2$day %in% df1$day)
#Extract values
j1 <- df2$value[i1]
j2 <- df2$value[i1-1]
#Compute mean
j3 <- (j1+j2)/2
#Assign
df1$AVG <- j3
输出:
day AVG
1 2 12.5
2 5 10.0
3 7 22.5
,
您可以使用lag()
中的dplyr
来获取先前的值,以便计算滚动平均值。
library(dplyr)
df2 %>%
mutate(AVG = (value + lag(value)) / 2,.keep = "unused") %>%
right_join(df1,by = "day")
# day AVG
# 1 2 12.5
# 2 5 10.0
# 3 7 22.5
或通过zoo::rollmeanr()
:
df2 %>%
mutate(AVG = zoo::rollmeanr(value,2,fill = NA),by = "day")
# day AVG
# 1 2 12.5
# 2 5 10.0
# 3 7 22.5