R:缺少日期的累计和
R: Cumulative sum with missing dates
我有两个数据框,一个(数据框 1)有日期和每个日期的一些观察值。在另一个 table(数据框 2)中,我的日期比另一个数据框 更多 。
我想做的是计算数据帧 1 的累计和并将结果放在数据帧 2 中。数据帧 2 中存在但数据帧 1 中不存在的任何日期都应该只包含前一天的值
数据框 1
Date Obs
2015-01-10 2
2015-01-11 3
2015-01-16 1
2015-01-20 4
数据框 2
Date cumSum
2015-01-09 0
2015-01-10 2
2015-01-11 5
2015-01-12 5
2015-01-13 5
2015-01-14 5
2015-01-15 5
2015-01-16 6
2015-01-17 6
2015-01-18 6
2015-01-19 6
2015-01-20 10
2015-01-21 10
如果有任何不清楚的地方,请告诉我。
任何帮助都会很棒!
谢谢,
麦克
我们可以使用 data.table
的开发版本,即 v1.9.5
(安装开发版本的说明是 here
。
我们将第一个'data.frame'('df1')转换为'data.table'(setDT(df1)
),与'df2'的'Date'列连接使用 on
选项(在开发版本中可用)。我们根据 'Obs' 中的非 NA 元素创建 'Cumsum' 列,方法是对 i (!is.na(Obs)
) 中的行索引指定的 'Obs' 进行累加和。然后,我们可以使用 library(zoo)
中的 na.locf
将 NA
值替换为非 NA 先前值并更新 'Cumsum' 列。由于 'Obs' 列不在预期的输出中,我们可以将 (:=
) 分配给 NULL。
library(data.table)#v1.9.5+
library(zoo)
res <- setDT(df1)[df2['Date'], on='Date'][!is.na(Obs), Cumsum:=cumsum(Obs)
][, Cumsum:=na.locf(Cumsum, na.rm=FALSE)][, Obs := NULL]
res
# Date Cumsum
# 1: 2015-01-09 NA
# 2: 2015-01-10 2
# 3: 2015-01-11 5
# 4: 2015-01-12 5
# 5: 2015-01-13 5
# 6: 2015-01-14 5
# 7: 2015-01-15 5
# 8: 2015-01-16 6
# 9: 2015-01-17 6
#10: 2015-01-18 6
#11: 2015-01-19 6
#12: 2015-01-20 10
#13: 2015-01-21 10
如果需要,我们可以将 'Cumsum' 中的 NA
值替换为“0”
res[is.na(Cumsum), Cumsum:=0]
或者正如@Khashaa 在评论中提到的那样,我们可以在没有 na.locf
的情况下使用 roll=Inf
setDT(df1)[,cumSum:=cumsum(Obs),][df2['Date'],
on='Date',roll=Inf][, Obs:= NULL][]
或者另一种选择是 match
和 na.locf
来获取数字索引并将非 NA 索引(来自 match
)替换为 'Obs' 的累加和, 像以前一样使用 na.locf
如果需要,我们可以将 NA
替换为 0.
df2$Cumsum <- na.locf(cumsum(df1$Obs)[match(df2$Date, df1$Date)], na.rm=FALSE)
数据
df1 <- structure(list(Date = structure(c(16445, 16446, 16451, 16455),
class = "Date"),
Obs = c(2L, 3L, 1L, 4L)), .Names = c("Date", "Obs"),
row.names = c(NA, -4L), class = "data.frame")
df2 <- structure(list(Date = structure(c(16444, 16445, 16446, 16447,
16448, 16449, 16450, 16451, 16452, 16453, 16454, 16455, 16456
), class = "Date"), cumSum = c(0L, 2L, 5L, 5L, 5L, 5L, 5L, 6L,
6L, 6L, 6L, 10L, 10L)), .Names = c("Date", "cumSum"), row.names = c(NA,
-13L), class = "data.frame")
我有两个数据框,一个(数据框 1)有日期和每个日期的一些观察值。在另一个 table(数据框 2)中,我的日期比另一个数据框 更多 。
我想做的是计算数据帧 1 的累计和并将结果放在数据帧 2 中。数据帧 2 中存在但数据帧 1 中不存在的任何日期都应该只包含前一天的值
数据框 1
Date Obs
2015-01-10 2
2015-01-11 3
2015-01-16 1
2015-01-20 4
数据框 2
Date cumSum
2015-01-09 0
2015-01-10 2
2015-01-11 5
2015-01-12 5
2015-01-13 5
2015-01-14 5
2015-01-15 5
2015-01-16 6
2015-01-17 6
2015-01-18 6
2015-01-19 6
2015-01-20 10
2015-01-21 10
如果有任何不清楚的地方,请告诉我。 任何帮助都会很棒!
谢谢,
麦克
我们可以使用 data.table
的开发版本,即 v1.9.5
(安装开发版本的说明是 here
。
我们将第一个'data.frame'('df1')转换为'data.table'(setDT(df1)
),与'df2'的'Date'列连接使用 on
选项(在开发版本中可用)。我们根据 'Obs' 中的非 NA 元素创建 'Cumsum' 列,方法是对 i (!is.na(Obs)
) 中的行索引指定的 'Obs' 进行累加和。然后,我们可以使用 library(zoo)
中的 na.locf
将 NA
值替换为非 NA 先前值并更新 'Cumsum' 列。由于 'Obs' 列不在预期的输出中,我们可以将 (:=
) 分配给 NULL。
library(data.table)#v1.9.5+
library(zoo)
res <- setDT(df1)[df2['Date'], on='Date'][!is.na(Obs), Cumsum:=cumsum(Obs)
][, Cumsum:=na.locf(Cumsum, na.rm=FALSE)][, Obs := NULL]
res
# Date Cumsum
# 1: 2015-01-09 NA
# 2: 2015-01-10 2
# 3: 2015-01-11 5
# 4: 2015-01-12 5
# 5: 2015-01-13 5
# 6: 2015-01-14 5
# 7: 2015-01-15 5
# 8: 2015-01-16 6
# 9: 2015-01-17 6
#10: 2015-01-18 6
#11: 2015-01-19 6
#12: 2015-01-20 10
#13: 2015-01-21 10
如果需要,我们可以将 'Cumsum' 中的 NA
值替换为“0”
res[is.na(Cumsum), Cumsum:=0]
或者正如@Khashaa 在评论中提到的那样,我们可以在没有 na.locf
的情况下使用 roll=Inf
setDT(df1)[,cumSum:=cumsum(Obs),][df2['Date'],
on='Date',roll=Inf][, Obs:= NULL][]
或者另一种选择是 match
和 na.locf
来获取数字索引并将非 NA 索引(来自 match
)替换为 'Obs' 的累加和, 像以前一样使用 na.locf
如果需要,我们可以将 NA
替换为 0.
df2$Cumsum <- na.locf(cumsum(df1$Obs)[match(df2$Date, df1$Date)], na.rm=FALSE)
数据
df1 <- structure(list(Date = structure(c(16445, 16446, 16451, 16455),
class = "Date"),
Obs = c(2L, 3L, 1L, 4L)), .Names = c("Date", "Obs"),
row.names = c(NA, -4L), class = "data.frame")
df2 <- structure(list(Date = structure(c(16444, 16445, 16446, 16447,
16448, 16449, 16450, 16451, 16452, 16453, 16454, 16455, 16456
), class = "Date"), cumSum = c(0L, 2L, 5L, 5L, 5L, 5L, 5L, 6L,
6L, 6L, 6L, 10L, 10L)), .Names = c("Date", "cumSum"), row.names = c(NA,
-13L), class = "data.frame")