在R中使用mutate_at合并重复行遇报错,求解决方案
问题:合并重复城市行(基于geocode补全缺失值)
我有一个包含400个变量(含字符型和数值型)的美国城市数据集,要求每行对应唯一城市,但存在大量重复行,重复行的缺失值可以互补,唯一标识为geocode。
当前数据示例:
geocode x y 8049 NA 7 8049 2 NA 2045 NA 9 2045 3 NA
期望结果:
geocode x y 8049 2 7 2045 3 9
我尝试了以下代码:
vars <- ls(df) vars <- vars[vars != "geocode" & vars != "State_name"] max <- function(x) max(x, na.rm = TRUE) df = df %>% group_by(geocode) %>% mutate_at(vars, max)
但出现报错:
Error in `mutate()`: ... Caused by error in `max()`: ! unused argument (na.rm = T)
移除na.rm = T后又报错:
Error: C stack usage is too close to the limit
仅保留数值型变量时仍出现相同错误,求解决方法。
解决方法
1. 避免覆盖内置函数
你自定义的max函数和R内置的max重名,导致调用时参数冲突,直接使用匿名函数或指定内置函数即可,无需重新定义。
2. 改用聚合函数而非行填充
mutate_at会保留所有重复行,仅将聚合结果重复填充,这会导致数据量无变化,甚至因重复计算触发C栈溢出。改用summarise_at(或across)直接将每组聚合为一行,更高效。
3. 适配数值型与字符型变量的处理方案
方案一:分类型聚合
针对数值型变量用max(na.rm=TRUE)取非缺失最大值,字符型变量取第一个非缺失值(假设每组字符型非缺失值唯一):
library(dplyr) # 分离数值型和字符型变量(排除标识列) num_vars <- df %>% select(-geocode, -State_name) %>% select(where(is.numeric)) %>% colnames() char_vars <- df %>% select(-geocode, -State_name) %>% select(where(is.character)) %>% colnames() # 分组聚合 df_clean <- df %>% group_by(geocode) %>% summarise( # 处理数值型变量 across(all_of(num_vars), ~max(., na.rm = TRUE)), # 处理字符型变量 across(all_of(char_vars), ~first(na.omit(.))) ) %>% # 合并唯一的State_name(每个geocode对应唯一州名) left_join(df %>% select(geocode, State_name) %>% distinct(), by = "geocode") %>% # 调整列顺序 select(geocode, State_name, everything()) # 处理数值型全为NA时返回的-Inf,替换为NA df_clean <- df_clean %>% mutate(across(all_of(num_vars), ~ifelse(is.infinite(.), NA, .)))
方案二:用fill补全后去重(更简洁)
如果每组的缺失值是互补分散的,直接按geocode分组后用fill补全上下缺失值,再去重即可,无需区分变量类型:
library(dplyr) library(tidyr) df_clean <- df %>% group_by(geocode) %>% fill(everything(), .direction = "downup") %>% # 上下方向补全缺失值 distinct(geocode, .keep_all = TRUE) # 保留每组唯一行
内容的提问来源于stack exchange,提问作者trinitysara
相关产品推荐
相关产品推荐

