[英]How to build a tibble from vectors/lists while applying `unique()` on them, without repeating calling `unique()` on every each?
I have several vectors and lists, for example:我有几个向量和列表,例如:
colors <- c("blue", "blue", "red", "green", "green")
shapes <- c("square", "square", "triangle", "triangle", "circle")
numbers <- c(22, 50, 50, 50, 13, 13)
list_of_dfs <- list(mtcars, mtcars, iris, iris, trees, trees, trees)
is_foo <- c(TRUE, FALSE, TRUE)
It is not a coincidence that except for is_foo
, all other objects are of the same length after calling unique()
on them.除了is_foo
之外,所有其他对象在调用unique()
后都具有相同的长度,这并非巧合。
I want to build a tibble such that I take the unique()
of some (but not all) such that:我想构建一个小标题,以便我采用一些(但不是全部)的unique()
,这样:
library(tibble)
my_tib <-
tibble(colors = unique(colors),
shapes = unique(shapes),
numbers = unique(numbers),
dfs = unique(list_of_dfs),
is_foo = is_foo)
My problem: I want to build my_tib
in a more succinct way .我的问题:我想以更简洁的方式构建my_tib
。 Meaning, I don't want to call unique()
on each column separately, but all at once for the columns that need to be unique
'ed (in this case, all except for is_foo
that goes as-is).意思是,我不想在每一列上分别调用unique()
,而是对需要unique
的列一次调用(在这种情况下,除了is_foo
之外的所有列都按原样调用)。
How can we do so if colors
, shapes
, numbers
, list_of_dfs
, and is_foo
are given ?如果给出colors
、 shapes
、 numbers
、 list_of_dfs
和is_foo
,我们该怎么做?
You can build a list first and use purrr:modify_at
to apply unique
to only selected elements.您可以先构建一个列表并使用purrr:modify_at
将unique
性应用于仅选定的元素。 purrr::modify_at
also allows tidyselect syntax so you have better control over the elements you want to modify. purrr::modify_at
还允许使用 tidyselect 语法,因此您可以更好地控制要修改的元素。 However, I don't see the point here since it does not shorten your code or reduce the number of operations to perform.但是,我看不到这里的重点,因为它不会缩短您的代码或减少要执行的操作数量。
library(tibble)
library(purrr)
as_tibble(modify_at(list(
colors = colors,
shapes = shapes,
numbers = numbers,
dfs = list_of_dfs,
is_foo = is_foo
), vars(!is_foo), unique))
Output Output
# A tibble: 3 x 5
colors shapes numbers dfs is_foo
<chr> <chr> <dbl> <list> <lgl>
1 blue square 22 <df [32 x 11]> TRUE
2 red triangle 50 <df [150 x 5]> FALSE
3 green circle 13 <df [31 x 3]> TRUE
Or maybe use mget
to get the variables so that you do not have to list them all.或者也许使用mget
来获取变量,这样您就不必全部列出它们。
cols <- c("colors", "shapes", "numbers", "list_of_dfs", "is_foo")
as_tibble(modify_at(mget(cols), vars(!is_foo), unique))
Output Output
# A tibble: 3 x 5
colors shapes numbers list_of_dfs is_foo
<chr> <chr> <dbl> <list> <lgl>
1 blue square 22 <df [32 x 11]> TRUE
2 red triangle 50 <df [150 x 5]> FALSE
3 green circle 13 <df [31 x 3]> TRUE
Making use of a helper function which makes use of tibble::lst
you could do:使用帮助器 function ,它利用 tibble tibble::lst
你可以这样做:
Note: At least for the general case multiple columns to add as is I failed to pass the columns as a simple list.注意:至少对于一般情况下要添加多个列,我未能将列作为简单列表传递。 Instead they have to be wrapped inside tibble::lst
.相反,它们必须被包裹在tibble::lst
中。
library(dplyr)
make_tibble <- function(..., add) {
args <- lapply(lst(...), unique)
tibble(!!!c(args, add))
}
make_tibble(colors, shapes, numbers, list_of_dfs, add = lst(is_foo, bar))
#> # A tibble: 3 × 6
#> colors shapes numbers list_of_dfs is_foo bar
#> <chr> <chr> <dbl> <list> <lgl> <int>
#> 1 blue square 22 <df [32 × 11]> TRUE 1
#> 2 red triangle 50 <df [150 × 5]> FALSE 2
#> 3 green circle 13 <df [31 × 3]> TRUE 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.