R语言使用tapply调用依分段数据变化的UDF并替代循环的方法
报错原因
tapply()的第一个参数要求传入和分组因子等长的向量,你传入完整数据框iris自然触发长度不匹配报错- 额外低级错误:你代码中写的
iris$species是小写开头,iris原生数据集的物种列名为大写开头的Species,即便第一个参数正确也会因为取不到分组因子报错
替代实现方案
你的需求是对按分组拆分后的完整子数据框应用自定义函数,有多种替代循环的实现方式:
方案1:基础包by()函数(最贴合你的使用习惯)
by()是专门针对数据框分组处理的基础包函数,逻辑和你预期的tapply用法完全一致,直接替换即可:
# 按Species拆分iris,对每个子数据框运行testFunction by_res <- by(iris, iris$Species, testFunction, factList = factorList) # 转成向量即可得到和你原循环输出完全一致的ansArr ansArr <- as.vector(by_res)
方案2:基础包split() + lapply()组合
先手动按分组拆分数据框,再对每个子数据框应用函数:
# 按Species拆分iris得到子数据框列表,遍历列表运行函数 split_res <- lapply(split(iris, iris$Species), testFunction, factList = factorList) ansArr <- unlist(split_res)
方案3:tidyverse风格分组汇总(更易扩展维护)
如果可以用第三方包,dplyr的分组汇总写法更直观,还能同时输出中间计算结果:
library(dplyr) # 自定义计算逻辑直接写在summarise里即可,不需要单独封装testFunction也可以 res_df <- iris %>% group_by(Species) %>% summarise( mean_sepal = mean(Sepal.Length), add_val = factorList[[as.character(first(Species))]], final_res = mean_sepal + add_val )
内容的提问来源于stack exchange,提问作者AKA
相关产品推荐
相关产品推荐

