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

使用dplyr::complete()按站点运营起止年展开数据集报错求助

将站点运营年份范围展开为逐年记录

编辑:尽管此问题已关闭,但需注意,现有答案采用的dplyr方法与2012年原问题的解法差异较大,这些新答案可能对其他用户有帮助。

我有一份包含各站点运营起止年份(minY、maxY)的数据集,希望将其展开为每个运营年份对应一行的形式。

示例数据集

set.seed(42)
df <- data.frame(
  site = rep(LETTERS[1:10]),
  minY = sample(1980:1990, 10),
  maxY = sample(2000:2010, 10)
)
df
   site minY maxY
1     A 1980 2007
2     B 1984 2006
3     C 1990 2003
4     D 1988 2000
5     E 1981 2004
6     F 1983 2005
7     G 1986 2008
8     H 1989 2001
9     I 1987 2009
10    J 1985 2010

最终数据集中,A站点应有28行(对应每个运营年份)。

尝试的方法及报错

我尝试使用complete()函数实现,但持续报错:

complete(df,
         nesting(site),
         fill = list(value1 = minY, value2 = maxY))
Error in vec_is_list(replace) : object 'minY' not found

解决方案

方法1:tidyverse简洁实现(推荐)

利用dplyr分组后结合tidyr::complete生成年份序列,这是最直观的tidyverse方法:

library(dplyr)
library(tidyr)

df_expanded <- df %>%
  group_by(site) %>%
  complete(year = minY:maxY) %>%
  ungroup()

# 验证A站点行数
nrow(filter(df_expanded, site == "A")) # 输出28,符合要求

方法2:逐行生成序列再展开

如果需要保留原有的minY和maxY列,也可以先按行生成年份列表,再展开:

df_expanded <- df %>%
  rowwise() %>%
  mutate(year = list(minY:maxY)) %>%
  unnest(year) %>%
  ungroup()

方法3:基础R实现

无需额外包的情况下,用lapply遍历每行生成对应数据框,再合并:

df_expanded <- do.call(rbind, lapply(1:nrow(df), function(i) {
  data.frame(
    site = df$site[i],
    year = seq(df$minY[i], df$maxY[i]),
    minY = df$minY[i],
    maxY = df$maxY[i]
  )
}))

关于complete()报错的原因

你之前的complete()用法错误,该函数的核心是补全已存在的分组组合,而非生成连续序列。正确的用法需要在分组后,指定year的序列范围为当前组的minY到maxY,如方法1所示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:10:28