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

如何扩展DataFrame补全缺失Family的Presence值(设为0)

问题描述

我有一个包含以下结构的DataFrame:

FamilyOrderClassPresenceYearSiteLocationLatLong
AeshnidaeOdonataInsecta02021KAV01NASS-17.418.5
AeshnidaeOdonataInsecta02023KAV01NASS-17.418.5
AeshnidaeOdonataInsecta12021KAV02NASS-17.718.7
AeshnidaeOdonataInsecta02023KAV02NASS-17.718.7
AeshnidaeOdonataInsecta02021KAV03NASS-17.819.1
AeshnidaeOdonataInsecta02023KAV03NASS-17.819.1

数据集共有100个唯一的Family,但部分站点(比如KAV03)只覆盖了90个Family的存在/缺失(Presence)值。我需要补全每个站点中缺失的Family条目,将这些条目的Presence设为0,同时保留其余变量的原有值。

我尝试了以下代码但未成功:

MorphoData <- expand.grid(
  Site = unique(MorphoData$Site), 
  Family = unique(MorphoData$Family), 
  Year = unique(MorphoData$Year)
) %>%
  left_join(MorphoData, by = c("Site", "Family", "Year")) %>%
  group_by(Site, Family, Year) %>%
  mutate(
    Presence = replace_na(Presence, 0)  # Ensure missing Presence values are 0
  ) %>%
  group_by(Site, Year) %>%
  fill(everything(.), .direction = "downup") %>%  # Fill missing taxonomy/spatial data
  ungroup()

数据示例如下:

data <- data_frame(Site = c("KAV01", "KAV01", "KAV01", "KAV01", "KAV01", "KAV01", "KAV01",
                            "KAV02", "KAV02", "KAV02", "KAV02", "KAV02", "KAV02", "KAV02",
                            "KAV03", "KAV03", "KAV03", "KAV03", "KAV03", "KAV03", "KAV03"),
                   Family = sample(c("Fam1", "Fam2", "Fam3", "Fam4", "Fam5", "Fam6"), 21, replace = TRUE),
                   Year = sample(c(2021, 2022, 2023), 21, replace = TRUE),
                   Presence = sample(c(0, 1), 21, replace = TRUE),
                   Lon = rnorm(n = 21, mean = 5, sd = 1),
                   Lat = rnorm(n = 21, mean = 2, sd = 0.3))

可以看到各站点并未包含所有Family,我希望补全这些缺失的Family并将其Presence设为0。


解决方案

你的代码问题出在填充非缺失变量的分组逻辑,以及expand.grid生成组合时可能遗漏完整Family列表的问题。修正思路如下:

  1. 先提取每个站点(Site)对应的固定属性(比如Location、Lat、Long),以及每个Family对应的分类属性(Order、Class),避免填充时出错;
  2. 生成Site、Family、Year的完整笛卡尔积;
  3. 先关联固定属性,再关联原始数据中的Presence,最后补全缺失值。

修正后的代码

library(dplyr)
library(tidyr)

# 提取每个Site对应的固定空间属性(确保每个Site对应唯一值)
site_attrs <- MorphoData %>%
  distinct(Site, Location, Lat, Long)

# 提取每个Family对应的分类属性(确保每个Family对应唯一值)
family_attrs <- MorphoData %>%
  distinct(Family, Order, Class)

# 生成完整的Site-Family-Year组合
# 注意:如果原始数据中未包含全部100个Family,需手动传入完整的Family列表替换unique(MorphoData$Family)
full_combinations <- expand.grid(
  Site = unique(MorphoData$Site),
  Family = unique(MorphoData$Family),
  Year = unique(MorphoData$Year)
) %>%
  as_tibble()

# 补全数据
MorphoData_full <- full_combinations %>%
  # 关联站点固定属性
  left_join(site_attrs, by = "Site") %>%
  # 关联分类固定属性
  left_join(family_attrs, by = "Family") %>%
  # 关联原始数据中的Presence值
  left_join(MorphoData %>% select(Site, Family, Year, Presence), 
            by = c("Site", "Family", "Year")) %>%
  # 将缺失的Presence设为0
  mutate(Presence = replace_na(Presence, 0))

代码说明

  • 拆分提取固定属性:每个站点的空间信息、每个Family的分类信息都是固定值,单独提取后再关联,避免用fill时出现错误填充;
  • 生成完整组合后,按逻辑依次关联属性和Presence,最后补全缺失值,逻辑更清晰,避免分组填充带来的冗余问题;
  • 如果原始数据未包含全部100个Family,需手动传入完整的Family列表(比如full_family_list <- c("Fam1", "Fam2", ..., "Fam100"))替换unique(MorphoData$Family)。

针对示例数据的测试代码

library(dplyr)
library(tidyr)

# 提取站点固定属性(示例中每个Site的Lon/Lat是随机生成的,实际应取每个Site的唯一值)
site_attrs <- data %>%
  distinct(Site, .keep_all = TRUE) %>%
  select(Site, Lon, Lat)

# 传入完整的Family列表,而非从示例数据中提取(避免遗漏)
full_families <- c("Fam1", "Fam2", "Fam3", "Fam4", "Fam5", "Fam6")

# 生成完整组合
full_combinations <- expand.grid(
  Site = unique(data$Site),
  Family = full_families,
  Year = unique(data$Year)
) %>%
  as_tibble()

# 补全数据
data_full <- full_combinations %>%
  left_join(site_attrs, by = "Site") %>%
  left_join(data %>% select(Site, Family, Year, Presence), 
            by = c("Site", "Family", "Year")) %>%
  mutate(Presence = replace_na(Presence, 0))

内容的提问来源于stack exchange,提问作者Daniel Estévez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 14:30:07