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

分组变量执行lag/lead时间序列操作时出现NA值的技术求助

分组计算滞后/超前值时全为NA的问题解决办法

在按分组执行滞后(lag)和超前(lead)操作时,所有结果都返回NA。尝试过dplyr::lag和data.table的分组操作,相关数据、代码及问题如下:

测试数据

test = structure(list(cnty90 = c(1005, 1005, 1005, 1005, 1005, 1005, 
                                 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1015, 
                                 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 
                                 1015, 1015, 1015, 1015, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 
                                 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1039, 1039), 
                      year = c(1868, 1872, 1876, 1880, 1884, 1888, 1892, 1896, 1900,
                               1904, 1908, 1912, 1916, 1920, 1924, 1928, 1868, 1872, 1876, 1880,
                               1884, 1888, 1892, 1896, 1900, 1904, 1908, 1912, 1916, 1920, 1924,
                               1928, 1868, 1872, 1876, 1880, 1884, 1888, 1892, 1896, 1900, 1904,
                               1908, 1912, 1916, 1920, 1924, 1928, 1868, 1872), 
                      numdailies = c(0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
                                     0, 2,2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
                                     0, 0, 0, 0, 1, 0, 0, 0, 0, 0)), row.names = c(NA, 50L), class = "data.frame")

原错误代码及结果

dplyr版本

test %>% 
    group_by(cnty90, year) %>% 
    mutate(numdailies_l1 = lag(numdailies, n = 1),
           changedailies_for=lead(numdailies, n=1))

执行后所有滞后和超前列均为NA:

# A tibble: 50 x 6
# Groups:   cnty90, year [50]
   cnty90  year numdailies numdailies_l1 changedailies changedailies_for
    <dbl> <dbl>      <dbl>         <dbl>         <dbl>             <dbl>
 1   1005  1868          0            NA            NA                NA
 2   1005  1872          0            NA            NA                NA
 3   1005  1876          0            NA            NA                NA
 4   1005  1880          0            NA            NA                NA
 5   1005  1884          2            NA            NA                NA
 6   1005  1888          2            NA            NA                NA
 7   1005  1892          2            NA            NA                NA
 8   1005  1896          1            NA            NA                NA
 9   1005  1900          1            NA            NA                NA
10   1005  1904          1            NA            NA                NA
# ... with 40 more rows

data.table版本

test = data.table::data.table(test)
test[, ":=" (numdailies_l1 = lag(numdailies, n = 1),
             changedailies=numdailies-numdailies_l1,
             changedailies_for=lead(numdailies, n=1)), by = .(cnty90, year)]

期望结果

# A tibble: 20 x 6
   cnty90  year numdailies numdailies_l1 changedailies changedailies_for
    <int> <int>      <int>         <int>         <int>             <int>
 1   1005  1868          0            NA            NA                 0
 2   1005  1872          0             0             0                 0
 3   1005  1876          0             0             0                 0
 4   1005  1880          0             0             0                 2
 5   1005  1884          2             0             2                 0
 6   1005  1888          2             2             0                 0
 7   1005  1892          2             2             0                -1
 8   1005  1896          1             2            -1                 0
 9   1005  1900          1             1             0                 0
10   1005  1904          1             1             0                 0
11   1005  1908          1             1             0                 0
12   1005  1912          1             1             0                 0
13   1005  1916          1             1             0                 0
14   1005  1920          1             1             0                 0
15   1005  1924          1             1             0                 0
16   1005  1928          1             1             0                NA
17   1015  1868          0            NA            NA                 0
18   1015  1872          0             0             0                 0
19   1015  1876          0             0             0                 0
20   1015  1880          0             0             0                 0

问题原因及修正方案

问题核心

错误地将year加入分组条件,每个cnty90+year组合仅对应一行数据,导致lag()和lead()无法找到同组内的其他行,因此返回NA。正确的分组逻辑应该是仅按地区cnty90分组,同时确保每个分组内的数据按year排序(保证滞后/超前的顺序正确)。

修正后的dplyr代码

library(dplyr)

test %>%
  arrange(cnty90, year) %>%  # 显式按地区和年份排序,确保顺序正确
  group_by(cnty90) %>%       # 仅按cnty90分组
  mutate(
    numdailies_l1 = lag(numdailies, n = 1),
    changedailies = numdailies - numdailies_l1,
    changedailies_for = lead(numdailies, n = 1)
  ) %>%
  ungroup()  # 可选,取消分组状态

修正后的data.table代码

library(data.table)

setDT(test)
test[order(cnty90, year),  # 先按地区和年份排序
     `:=`(
       numdailies_l1 = lag(numdailies, n = 1),
       changedailies = numdailies - numdailies_l1,
       changedailies_for = lead(numdailies, n = 1)
     ),
     by = cnty90]  # 仅按cnty90分组

执行上述修正代码后,即可得到符合预期的滞后/超前计算结果。

内容的提问来源于stack exchange,提问作者cdcarrion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:20:57