如何在模型数据表中用数据框名称列构建模型?解决eval报错问题
解决在Tibble中按数据集名称批量拟合模型的问题
我明白你遇到的困扰了——明明单独调用每个数据集跑模型都没问题,但放到mutate里批量处理就报错,咱们来拆解原因和解决办法:
报错原因分析
你遇到的Error: Only strings can be converted to symbols.,核心问题在于:
- 单独运行
eval(sym('df1'))时,'df1'是单个字符串,sym()可以正常把它转换成符号; - 但在
mutate里直接用dataset时,它是一个长度为2的字符向量,sym()只能处理单个字符串,没法直接对向量操作,所以触发报错。
解决方案
下面提供几种符合tidyverse风格的解决方法,任选其一即可:
方法1:用rowwise()按行处理
先通过rowwise()让mutate逐行处理每个数据集名称,这样每一行的dataset都是单个字符串,就能正常用sym()转换了。注意要把模型结果用list()包裹,因为每个模型是一个对象,需要存在列表列里:
results <- results %>% rowwise() %>% mutate(model = list(lm(z ~ x + y, data = eval(sym(dataset))))) %>% ungroup() # 处理完记得取消按行分组
方法2:用purrr::map()遍历处理
map()函数会自动遍历dataset列的每个元素,逐个处理字符串,返回的结果天然是列表,完美适配tibble的列表列:
results <- results %>% mutate(model = map(dataset, ~ lm(z ~ x + y, data = eval(sym(.x)))))
这里的.x代表map遍历到的每个数据集名称字符串。
方法3:用数据集列表(更安全的方式)
如果不想用eval()(毕竟eval存在一定的安全风险,尤其是处理未知输入时),可以先把所有数据集放到一个命名列表里,然后通过列表索引调用:
# 先创建命名数据集列表 dataset_list <- list(df1 = df1, df2 = df2) # 批量拟合模型 results <- results %>% mutate(model = map(dataset, ~ lm(z ~ x + y, data = dataset_list[[.x]])))
验证结果
处理完成后,你可以通过以下方式查看模型结果:
# 查看第一个模型的摘要 summary(results$model[[1]]) # 查看第二个模型的系数 coef(results$model[[2]])
内容的提问来源于stack exchange,提问作者David Pepper
相关产品推荐
相关产品推荐

