You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在dplyr的mutate语句中使用get函数时出现错误的排查

问题:rowwise()环境下调用get(name)报错的原因与解决

先重现场景:
创建两个对象:

tmp <- list(1,2,4)
dafa <- data.frame(thing="Yes", 
            value=4)

用typeof()查看时,列表和数据框都返回list:

typeof(get("tmp"))  # list
typeof(get("dafa")) # list

需求是生成包含环境中所有对象的数据框,并标记哪些是数据框,于是编写代码:

library(tidyverse)
# 获取环境中所有对象并存储为表格
data_items <- map_dfr(ls(), \(itm){
    data.frame(name=itm, 
               type=typeof(get(itm)), 
               size=object.size(get(itm)))})

# 调整每行以标记对象是否为数据框
data_items %>% rowwise() %>%
mutate(type = ifelse(inherits(get(name), "data.frame"),
                   "data.frame",
                   type))

运行后报错:

Error in get(name) : first argument has length > 1

原因分析

虽然使用了rowwise(),但get()函数并不识别tidyverse的行上下文,它会直接接收整个name列的向量(长度大于1),而get()要求第一个参数必须是单个字符串,因此触发报错。rowwise()主要让聚合类函数(如sum、mean)按行计算,但对get()这类基础函数不起作用。

解决方法

方法一:在rowwise中获取单行的name值

用pick(name)在rowwise上下文里提取当前行的单个name字符串,传给get():

data_items %>% rowwise() %>%
  mutate(type = ifelse(inherits(get(pick(name)), "data.frame"),
                     "data.frame",
                     type))

或者用cur_data()获取当前行数据后提取name:

data_items %>% rowwise() %>%
  mutate(type = ifelse(inherits(get(cur_data()$name), "data.frame"),
                     "data.frame",
                     type))

方法二:提前在map阶段完成判断(更高效)

避免后续重复调用get(),直接在第一步遍历对象时就判断是否为数据框:

library(tidyverse)
data_items <- map_dfr(ls(), \(itm){
  obj <- get(itm) # 只调用一次get,提升效率
  data.frame(
    name = itm,
    type = if(inherits(obj, "data.frame")) "data.frame" else typeof(obj),
    size = object.size(obj)
  )
})

内容的提问来源于stack exchange,提问作者pluke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:35:20