You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言逐行应用函数跨表统计日度观测期数返回NA问题

问题原因

你的代码返回NA的核心问题出在apply()的运行机制上:
apply()处理输入时会先把数据框强制转换为矩阵,而矩阵仅支持存储单一类型的数据,因此你df1中存储的Date类型日期列会被自动转为字符串,传入匿名函数的行值x是字符型,和df2中存储的Date类型日期做大小比较时类型不匹配,最终返回NA。
你最开始直接写sum(df2$start <= df1$dates & df2$end>=df1$dates)的问题在于:R的比较运算符是向量化运算,长度不一致的向量比较时会触发循环规则,最终sum计算的是两个向量所有位置比较结果的总TRUE数,不是逐行对应每个日期的统计值。


可行解决方案

方案1:基础R无依赖实现

不要用apply遍历整个数据框,直接遍历df1$dates这个保留了Date类型的向量即可,逻辑和你最开始写的一致,不会触发类型转换问题:

df1$number <- sapply(df1$dates, function(current_date) {
  sum(df2$start <= current_date & df2$end >= current_date)
})

运行后得到的结果完全符合预期:

> df1
        dates number
1  2020-01-01      2
2  2020-01-02      2
3  2020-01-03      1
4  2020-01-04      0
5  2020-01-05      1
6  2020-01-06      1
7  2020-01-07      1
8  2020-01-08      1
9  2020-01-09      1
10 2020-01-10      2

方案2:大数据量高效向量化实现

如果你的数据量级很大,逐行遍历的性能较差,可以用事件累计的向量化写法,不需要逐行判断:

# 构造事件流:观测开始计数+1,观测结束次日计数-1
event_log <- rbind(
  data.frame(dt = df2$start, val = 1),
  data.frame(dt = df2$end + 1, val = -1)
)
# 按日期汇总变动值,计算累计生效数
event_log <- aggregate(val ~ dt, event_log, sum)
event_log$cum <- cumsum(event_log$val)
# 匹配回原df1,填充空值
df1 <- merge(df1, event_log, by.x = "dates", by.y = "dt", all.x = TRUE)
df1$number <- cumsum(c(0, replace(df1$val, is.na(df1$val), 0)))[-1]
df1 <- df1[, c("dates", "number")]

方案3:区间连接计数实现

你之前提到的区间连接方案并非只能做1:1匹配,连接后按日期分组计数同样可以得到正确结果,逻辑更直观:

library(dplyr)
library(fuzzyjoin)
library(tidyr)

df1 <- df1 %>%
  fuzzy_inner_join(
    df2,
    by = c("dates" = "start", "dates" = "end"),
    match_fun = list(`>=`, `<=`)
  ) %>%
  count(dates, name = "number") %>%
  right_join(df1, by = "dates") %>%
  mutate(number = replace_na(number, 0)) %>%
  arrange(dates)

内容的提问来源于stack exchange,提问作者Tan Sing Chee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:39:19