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

dplyr按行处理时如何批量将指定列值存入列表列对应键

批量将指定列值合并到列表列的对应键下

Stack Overflow上有不少类似问题,但大多围绕sum、mean这类简单函数展开,场景都能大幅简化。我需要实现的是:将指定列的值批量复制到列表列中对应的键下,以下是最小复现示例:

环境搭建

library(dplyr)
library(purrr)
library(rlang)
library(tibble)
library(magrittr)

keys <- c('a', 'b')

tbl <-
    tibble(
        x = list(
            list(f = 'foo', g = 'bar'),
            list(f = 'bar', g = 'foo')
        ),
        a = list(
            list(i = 1, j = 2),
            list(i = 4, j = 7)
        ),
        b = list(
            list(i = 5, j = 3),
            list(i = 2, j = 9)
        )
    )

单键手动实现(可行但繁琐)

需求是:让x的第一个元素中,键a和b分别对应列a和b的第一个值。手动逐个处理键的代码可以实现:

tbl2 <-
    tbl %>%
    rowwise %>%
    mutate(
        x = list(x %>% inset2('a', a) %>% inset2('b', b))
    )

但如果有12个键,就得调用12次inset2,显然不够高效,我想找到批量处理的方法。

尝试过的批量方法及问题

1. purrr::reduce结合.data pronoun

遍历键并尝试用.data[[key]]索引列,但报错:

tbl2 <-
    tbl %>%
    rowwise %>%
    mutate(
        x = list(
            reduce(
                keys,
                function(lst, key) {
                    inset2(lst, key, .data[[key]])
                },
                .init = x
            )
        )
    )

错误信息:

Error: object 'key' not found
7: quos(..., .ignore_empty = "all")
6: dplyr_quosures(...)
5: force(dots)
4: mutate_cols(.data, dplyr_quosures(...), by)
3: mutate.data.frame(., x = list(reduce(keys, function(lst, key) {
       inset2(lst, key, .data[[key]])
   }, .init = x)))
2: mutate(., x = list(reduce(keys, function(lst, key) {
       inset2(lst, key, .data[[key]])
   }, .init = x)))
1: tbl %>% rowwise %>% mutate(x = list(reduce(keys, function(lst,
       key) {
       inset2(lst, key, .data[[key]])
   }, .init = x)))

这里key本身是存在的字符串,但.data无法识别它。

2. 尝试将key转换为符号

把key转成符号后依然报错:

tbl2 <-
    tbl %>%
    rowwise %>%
    mutate(
        x = list(
            reduce(
                keys,
                function(lst, key) {
                    inset2(lst, key, !!sym(key))
                },
                .init = x
            )
        )
    )

错误信息:

Error: object 'key' not found
9: is_symbol(x)
8: sym(key)
7: quos(..., .ignore_empty = "all")
6: dplyr_quosures(...)
5: force(dots)
4: mutate_cols(.data, dplyr_quosures(...), by)
3: mutate.data.frame(., x = list(reduce(keys, function(lst, key) {
       inset2(lst, key, !!sym(key))
   }, .init = x)))
2: mutate(., x = list(reduce(keys, function(lst, key) {
       inset2(lst, key, !!sym(key))
   }, .init = x)))
1: tbl %>% rowwise %>% mutate(x = list(reduce(keys, function(lst,
       key) {
       inset2(lst, key, !!sym(key))
   }, .init = x)))

如果去掉!!,代码能运行,但赋值的是符号本身而非对应行的值:

tbl2 <-
    tbl %>%
    rowwise %>%
    mutate(
        x = list(
            reduce(
                keys,
                function(lst, key) {
                    inset2(lst, key, sym(key))
                },
                .init = x
            )
        )
    )

tbl2$x[[1]]$a
# 返回的是符号a,而非对应列的值

3. 使用reduce2传递键和值

尝试用reduce2同时传入键和对应列,但x最终全为NULL,推测!!!syms(keys)没有正确传递值:

tbl2 <-
    tbl %>%
    rowwise %>%
    mutate(
        x = list(
            reduce2(
                keys,
                !!!syms(keys),
                function(lst, key, val) {
                    inset2(lst, key, val)
                },
                .init = x
            )
        )
    )

4. 使用utils::modifyList批量合并

想一次性提取所有指定列合并到x中,但.data不支持[索引:

tbl2 <-
    tbl %>%
    rowwise %>%
    mutate(
        x = list(modifyList(x, .data[keys]))
    )

错误信息:

Error in `mutate()`:
ℹ In argument: `x = list(modifyList(x, .data[keys]))`.
ℹ In row 1.
Caused by error in `.data[keys]`:
! `[` is not supported by the `.data` pronoun, use `[[` or $ instead.
Run `rlang::last_trace()` to see where the error occurred.

求助

我已经找到一个可行方案,但总觉得过程太繁琐,想知道有没有更简洁的批量处理方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:28:12