R语言mutate()调用自定义函数计算县观测频数异常求助
问题解决:为每个县生成对应频数列
你的问题出在函数调用时的向量处理逻辑上:当你用mutate(cps, freq=f(county))时,传入函数f的是整个county列的向量,而非逐行的单个县名。函数里的sum(with(cps, county==x))实际是做逐元素相等比较(每行的county等于对应位置的x元素),最后求和得到的是整个数据框中元素自匹配的总数量(也就是总观测数),所以每行都得到相同的总数值。
下面是几种高效的正确实现方式:
方法1:dplyr分组计数(推荐)
利用dplyr的分组功能直接计算每组行数,这是最简洁高效的方式:
library(dplyr) cps <- cps %>% group_by(county) %>% # 按县分组 mutate(freq = n()) %>% # 每组的行数就是该县城的频数 ungroup() # 取消分组,恢复普通数据框结构
方法2:base R的ave函数
如果不想加载dplyr,用base R的ave函数也能实现:
cps$freq <- ave(rep(1, nrow(cps)), cps$county, FUN = sum)
ave会按county分组,对每组的重复值1求和,最终返回与原数据长度一致的频数向量。
方法3:先统计再合并
先单独统计每个县的频数,再通过关联合并回原数据框:
library(dplyr) # 先统计每个县的频数 county_freqs <- cps %>% count(county, name = "freq") # 合并到原数据框 cps <- cps %>% left_join(county_freqs, by = "county")
关于你原有代码的修改(不推荐)
如果一定要让你写的函数f生效,需要用rowwise()强制逐行处理,但这种方法在数据量大时效率极低,仅作参考:
cps <- cps %>% rowwise() %>% mutate(freq = f(county)) %>% ungroup()
内容的提问来源于stack exchange,提问作者Tilman
相关产品推荐
相关产品推荐

