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

如何用tidyverse根据列表列all_x的结构生成目标新列x2?

R语言tidyverse生成新列x2的解决方案

原始数据

待处理的数据框如下:

df <- structure(list(id = c("1358792", "1358792", "333482", "333482", "747475", "747475"),
                     x = c("123", "123", "456", "456", NA, NA),
                     all_x = list("123", "123",
                                  c("456", "789"),
                                  c("456", "789"),
                                  list(),
                                  list())),
                row.names = c(NA, -6L),
                class = "data.frame")

需求说明

需用tidyverse风格新增列x2,规则如下:

  • 若all_x列元素长度≤1,直接取x列对应值;
  • 若all_x列元素是长度为2的字符向量,按id分组后,取该组内对应行号的元素。

期望输出:

id    x    all_x   x2
1 1358792  123      123  123
2 1358792  123      123  123
3  333482  456 456, 789  456
4  333482  456 456, 789  789
5  747475 <NA>     NULL <NA>
6  747475 <NA>     NULL <NA>

原代码问题

你之前尝试的代码无法得到正确结果,原因是:

  • all_x[[1]]取的是整个数据框all_x列的第一个元素,而非分组后每组的all_x元素;
  • if_else更适合向量型条件判断,处理列表元素提取时,结合分组操作的case_when更适配。

正确代码

方法一:分组后提取

library(tidyverse)

df |>
  group_by(id) |>
  mutate(
    x2 = case_when(
      lengths(all_x) > 1 ~ all_x[[1]][row_number()],
      TRUE ~ x
    )
  ) |>
  ungroup()

方法二:用map2_chr结合.by参数(tidyverse 1.0.0+支持)

df |>
  mutate(
    x2 = case_when(
      lengths(all_x) > 1 ~ map2_chr(all_x, row_number(), ~ .x[.y]),
      TRUE ~ x
    ),
    .by = id
  )

两种方法都能生成符合要求的x2列,其中方法二无需显式分组/取消分组,更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 05:07:13