我有一个InternetClientServer
,其中一列是命名变量列表(它们本身主要是列表)。最好使用tbl_df
代码,我想在一组这些变量上应用一个函数,并将每个函数调用的输出转换为数据框中的一个新列(类似于{{1} }但是对于这些嵌套变量。)
例如,我目前的数据类似于:
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.
中的每个变量写出来(实际数据有~24个变量)。
编辑:另外,要明确的是,获取长度的示例只是一个函数,我想申请。我真的想要一种更通用的方法,在d %>%
mutate(n_a = purrr::map(l, ~length(.$a)) %>%
purrr::simplify(),
n_b = purrr::map(l, ~length(.$b)) %>%
purrr::simplify())
中的变量的任意子集上应用任意函数。
答案 0 :(得分:3)
您可以使用lengths
来提取元素&#39;没有环绕它们的长度;并使用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
答案 1 :(得分:2)
另一种选择是使用purrr包中的transpose
和lengths
功能。
bind_cols(d, map(transpose(d$l), lengths))
# # A tibble: 2 x 3
# l a b
# <list> <int> <int>
# 1 <list [2]> 4 3
# 2 <list [2]> 2 1
答案 2 :(得分:1)
您可以使用sapply
并将结果分配给新列:
d[,c("a","b")] <- t(sapply(d$l,lengths))
# # A tibble: 2 x 3
# l a b
# <list> <int> <int>
# 1 <list [2]> 4 3
# 2 <list [2]> 2 1