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

如何在dplyr的mutate中提取嵌套tibble列表列元素并解决报错?

问题场景
  • 测试tibble构造代码:
library(dplyr)
my_tib <- tibble(names = c("blah", "blah2"), data = list(1, c(2, 3)))
  • 数据默认打印结构:
names data     
  <chr> <list>   
1 blah  <dbl [1]>
2 blah2 <dbl [2]>
  • 值提取规则:对data列每个列表元素按规则提取值,生成data_min列:
    • 若元素长度为2,取第一个元素
    • 若元素长度为1且首元素大于10,返回NA_integer_
    • 若元素长度为1且首元素小于10,取首元素
  • 原触发报错的实现代码:
my_tib %>%
  rowwise() %>%
  mutate(data_min = case_when(lengths(data) == 2 ~ data[[1]],
                              lengths(data) == 1 & data[[1]] > 10 ~ NA_integer_,
                              lengths(data) == 1 & data[[1]] < 10 ~ data[[1]]))
  • 运行报错信息:
Error in `mutate()`:
! Problem while computing `data_min = case_when(...)`.
✖ `data_min` must be size 1, not 2.
ℹ Did you mean: `data_min = list(case_when(...))` ?
ℹ The error occurred in row 2.
Run `rlang::last_error()` to see where the error occurred.
  • 期望输出结果:
names data       data_min
  <chr> <list>     <int>
1 blah  <dbl [1]>  1
2 blah2 <dbl [2]>  2
报错原因

rowwise()会按行切分数据集,此时每行的data是列表中存储的原子向量本身。代码中使用的lengths()是向量化函数,作用是遍历传入对象的每个最外层元素返回长度:处理第二行data = c(2,3)时,lengths(data)会返回长度为2的向量c(1,1)(原子向量的每个标量元素长度都是1),导致case_when输出长度为2,和单行计算要求的长度1不匹配,触发报错。

修复方案

将所有判断逻辑中的lengths()替换为单对象长度计算函数length()即可,length()会直接返回当前行向量的总长度,符合行级计算逻辑:

my_tib %>%
  rowwise() %>%
  mutate(data_min = case_when(
    length(data) == 2 ~ data[[1]],
    length(data) == 1 & data[[1]] > 10 ~ NA_integer_,
    length(data) == 1 & data[[1]] < 10 ~ data[[1]]
  )) %>%
  ungroup()

运行后输出与预期完全一致:

# A tibble: 2 × 3
  names data     data_min
  <chr> <list>      <dbl>
1 blah  <dbl [1]>        1
2 blah2 <dbl [2]>        2

如果需要data_min严格为整数类型,在返回值外套一层as.integer()即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 06:01:20