如何用dplyr的mutate()函数归一化月份数不均的冬夏两季数据
问题解决:海豚观测数据的dplyr分组计算与归一化错误处理
需求背景
野外工作中按年度、月度收集珊瑚礁区域海豚观测数据,已划分为冬夏两季,需用dplyr完成:
- 计算每个珊瑚礁、每个季节的总观测数和平均种群规模
- 因冬季7个月、夏季5个月,需对总观测数按季节归一化
最终需输出两列:平均种群规模、归一化后的总观测数
报错信息
`summarise()` has grouped output by 'Reef_Code'. You can override using the `.groups` argument. Error in `mutate()`: ℹ In argument: `Normalized_Sightings = Total_Sightings/season_months[Season]`. ℹ In group 1: `Reef_Code = 1`. Caused by error in `Total_Sightings / season_months[Season]`: ! non-numeric argument to binary operator Run `rlang::last_trace()` to see where the error occurred.
原代码
library(dplyr) # 按季节长度归一化,冬季7个月、夏季5个月 season_months <- list("Winter" = 7, "Summer" = 5) # 按珊瑚礁和季节分组,计算总观测数、平均种群规模并归一化 result <- MyDf %>% group_by(Reef_Code, Season) %>% summarize( Total_Sightings = n(), # 每个珊瑚礁-季节的观测次数 Avg_Group_Size = mean(Group_Size, na.rm = TRUE)) %>% # 平均种群规模 mutate(Normalized_Sightings = Total_Sightings / season_months[Season]) # 按季节长度归一化
测试用数据集
MyDf <- structure(list(Reef_Code = c(1L, 2L, 3L, 1L, 1L, 3L, 2L, 4L, 2L, 5L, 4L, 2L, 3L, 6L, 5L, 3L, 6L, 6L, 4L, 2L, 5L, 4L, 1L, 2L, 3L, 4L, 6L, 1L, 1L, 2L, 3L, 6L, 5L, 3L, 6L, 6L, 4L, 2L, 5L, 4L, 3L, 1L, 1L, 3L, 2L, 4L, 2L, 5L, 4L, 2L, 3L, 6L, 5L, 3L, 5L, 4L, 2L, 3L, 6L), Season = c("Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Winter", "Summer", "Summer", "Summer", "Summer", "Summer", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Winter"), Group_Size = c(7L, 11L, 1L, 14L, 16L, 2L, 5L, 5L, 5L, 8L, 8L, 6L, 6L, 1L, 8L, 8L, 4L, 5L, 1L, 5L, 5L, 14L, 8L, 7L, 7L, 18L, 25L, 2L, 5L, 5L, 8L, 8L, 6L, 6L, 1L, 8L, 8L, 5L, 14L, 8L, 7L, 7L, 18L, 25L, 2L, 5L, 5L, 8L, 8L, 6L, 6L, 1L, 8L, 7L, 8L, 8L, 6L, 6L, 1L)), class = "data.frame", row.names = c(NA, -59L))
错误原因
- 列表索引错误:
season_months是列表类型,用season_months[Season]返回的是子列表而非数值,导致除法运算时出现“非数值参数”错误,需用双括号[[提取对应数值。 - 分组警告:
summarize默认会保留部分分组(此处保留了Reef_Code),需设置.groups参数明确分组处理方式,避免警告。
修正后的代码
方法一:使用列表双括号索引
library(dplyr) season_months <- list("Winter" = 7, "Summer" = 5) result <- MyDf %>% group_by(Reef_Code, Season) %>% summarize( Total_Sightings = n(), Avg_Group_Size = mean(Group_Size, na.rm = TRUE), .groups = "drop") %>% # 取消所有分组,避免后续操作的分组干扰 mutate(Normalized_Sightings = Total_Sightings / season_months[[Season]])
方法二:改用命名向量(更简洁)
将season_months定义为命名向量,直接用Season作为索引即可:
library(dplyr) season_months <- c("Winter" = 7, "Summer" = 5) # 命名向量 result <- MyDf %>% group_by(Reef_Code, Season) %>% summarize( Total_Sightings = n(), Avg_Group_Size = mean(Group_Size, na.rm = TRUE), .groups = "drop") %>% mutate(Normalized_Sightings = Total_Sightings / season_months[Season])
运行结果示例
运行修正后的代码后,会得到如下结构的数据集:
#> Reef_Code Season Total_Sightings Avg_Group_Size Normalized_Sightings #> 1 1 Summer 7 10.71429 1.40000 #> 2 1 Winter 3 4.33333 0.42857 #> 3 2 Summer 9 6.55556 1.80000 #> 4 2 Winter 7 5.71429 1.00000 #> ...
内容的提问来源于stack exchange,提问作者Alice Hobbs
相关产品推荐
相关产品推荐

