我有一个 tbl_df
,其中一列是命名变量列表(它们本身主要是列表)。最好使用 tidyverse
代码,我想在一组这些变量上应用一个函数,并将每个函数调用的输出转换为数据框中的一个新列(有点像 mutate_at
可以,但对于这些嵌套变量)。
例如,我当前的数据类似于这样:
d <- tibble(
l = list(list("a"=list("a1","a2","a3","a4"),
"b"=list("b1","b2","b3")),
list("a"=list("x1","x2"),
"b"=list("y3")))
)
# A tibble: 2 x 1
l
<list>
1 <list [2]>
2 <list [2]>
我想将函数应用于 d$l
中的变量(即 a
和 b
),方法与 mutate_at
会在您为其提供多个功能时自动创建以创建它们的变量命名的新列。例如,我想应用的一个函数会将它们的长度作为新列返回,即:
# A tibble: 2 x 3
l n_a n_b
<list> <dbl> <dbl>
1 <list [2]> 4. 3.
2 <list [2]> 2. 1.
有人知道这样做的简单方法吗?到目前为止,我一直在做这样的事情:
d %>%
mutate(n_a = purrr::map(l, ~length(.$a)) %>%
purrr::simplify(),
n_b = purrr::map(l, ~length(.$b)) %>%
purrr::simplify())
但我不想为 l
中的每个变量都写出来(真实数据有大约 24 个变量)。
编辑:另外,需要说明的是,获取长度的示例只是我想要应用的一个函数。我真的想要一种更通用的方法来对 l
中的变量的任意 子集 应用任意函数。
最佳答案
您可以使用lengths
来提取元素的长度,而无需循环遍历它们;并使用 bind_cols
而不是 mutate
将多列添加到数据框:
d %>% bind_cols(map_dfr(.$l, ~ as.list(lengths(.))))
# A tibble: 2 x 3
# l a b
# <list> <int> <int>
#1 <list [2]> 4 3
#2 <list [2]> 2 1
或者使用compose
链接as.list
和lengths
:
d %>% bind_cols(map_dfr(.$l, compose(as.list, lengths)))
# A tibble: 2 x 3
# l a b
# <list> <int> <int>
#1 <list [2]> 4 3
#2 <list [2]> 2 1
注意此方法动态检查列表的名称,如果缺少具有特定名称的元素,结果将给出 NA
:
d <- tibble(
l = list(list("a"=list("a1","a2","a3","a4")),
list("a"=list("x1","x2"),
"b"=list("y3")))
)
d %>% bind_cols(map_dfr(.$l, ~ as.list(lengths(.))))
# A tibble: 2 x 3
# l a b
# <list> <int> <int>
#1 <list [1]> 4 NA
#2 <list [2]> 2 1
关于r - 将嵌套在数据框中的列表中的变量转换为列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49593739/