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

set_names()返回character而非tbl_df等类型的原因排查

问题:用set_names为tibble列表命名时得到错误名称"character"的原因

我尝试用set_names函数给一个tibble列表命名,预期每个列表元素的名称是"tbl_df, tbl, data.frame",但实际返回的名称却是"character"。单独获取单个列表元素的类并拼接能得到预期结果,相关R代码示例如下:

library(tidyverse)

l1 <-  # Small list of short tibbles
diamonds |> 
  group_split(cut) |> 
  map(~ .x |> slice(1:2)) |> 
  head(2)

l1 |> # Trying to name them based on their class, but the result is "character" which is wrong:
  set_names(function(x) class(x) |> paste(collapse = ", "))
#> $character
#> # A tibble: 2 × 10
#>   carat cut   color clarity depth table price     x     y     z
#>   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1  0.22 Fair  E     VS2      65.1    61   337  3.87  3.78  2.49
#> 2  0.86 Fair  E     SI2      55.1    69  2757  6.45  6.33  3.52
#> 
#> $character
#> # A tibble: 2 × 10
#>   carat cut   color clarity depth table price     x     y     z
#>   <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1  0.23 Good  E     VS1      56.9    65   327  4.05  4.07  2.31
#> 2  0.31 Good  J     SI2      63.3    58   335  4.34  4.35  2.75


# Evidence that each element should be named "tbl_df, tbl, data.frame", not character
l1[[1]] |> 
  class() |> 
  paste(collapse = ", ")
#> [1] "tbl_df, tbl, data.frame"

原因分析

你用的purrr::set_names(tidyverse默认加载的是这个版本)的.fn参数,默认是处理列表的现有名称,而非列表元素本身:

  • 如果列表原本没有名称,它会把字符型的位置序号(比如"1"、"2")传给你定义的函数;
  • 你写的function(x) class(x)里的x其实是"1"这种字符串,class("1")返回的就是"character",所以最终所有元素的名称都变成了"character"。

而你单独测试时,是直接把列表里的tibble元素传给class(),自然能得到正确的类名组合。

解决方法

要实现按每个元素的类来命名,有两种简单方式:

方法1:先生成名称向量再传入set_names

l1 |> set_names(map_chr(l1, ~ class(.x) |> paste(collapse = ", ")))

方法2:直接给列表的names属性赋值

names(l1) <- map_chr(l1, ~ class(.x) |> paste(collapse = ", "))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:11:00