Dav*_*d T 6 r unnest dplyr tibble
我有一个返回小标题的函数。它运行正常,但我想对其进行矢量化。
library(tidyverse)
tibTest <- tibble(argX = 1:4, argY = 7:4)
square_it <- function(xx, yy) {
if(xx >= 4){
tibble(x = NA, y = NA)
} else if(xx == 3){
tibble(x = as.integer(), y = as.integer())
} else if (xx == 2){
tibble(x = xx^2 - 1, y = yy^2 -1)
} else {
tibble(x = xx^2, y = yy^2)
}
}
Run Code Online (Sandbox Code Playgroud)
mutate
当我用 调用它时map2
,它运行正常,给了我想要的结果:
tibTest %>%
mutate(sq = map2(argX, argY, square_it)) %>%
unnest()
## A tibble: 3 x 4
# argX argY x y
# <int> <int> <dbl> <dbl>
# 1 1 7 1 49
# 2 2 6 3 35
# 3 4 4 NA NA
Run Code Online (Sandbox Code Playgroud)
我第一次尝试对它进行矢量化失败了,我明白为什么 - 我无法返回小标题的矢量。
square_it2 <- function(xx, yy){
case_when(
x >= 4 ~ tibble(x = NA, y = NA),
x == 3 ~ tibble(x = as.integer(), y = as.integer()),
x == 2 ~ tibble(x = xx^2 - 1, y = yy^2 -1),
TRUE ~ tibble(x = xx^2, y = yy^2)
)
}
# square_it2(4, 2) # FAILS
Run Code Online (Sandbox Code Playgroud)
我的下一次尝试在一个简单的输入上运行正常。我可以返回一个 tibbles 列表,这就是我想要的unnest
square_it3 <- function(xx, yy){
case_when(
xx >= 4 ~ list(tibble(x = NA, y = NA)),
xx == 3 ~ list(tibble(x = as.integer(), y = as.integer())),
xx == 2 ~ list(tibble(x = xx^2 - 1, y = yy^2 -1)),
TRUE ~ list(tibble(x = xx^2, y = yy^2))
)
}
square_it3(4, 2)
# [[1]]
# # A tibble: 1 x 2
# x y
# <lgl> <lgl>
# 1 NA NA
Run Code Online (Sandbox Code Playgroud)
但是当我在 a 中调用它时mutate
,它并没有给我与square_it
. 我可以看出哪里出了问题。在xx == 2
子句中,xx
充当 2 的原子值。但在构建 tibble 时,xx
是一个长度为 4 的向量。
tibTest %>%
mutate(sq = square_it3(argX, argY)) %>%
unnest()
# # A tibble: 9 x 4
# argX argY x y
# <int> <int> <dbl> <dbl>
# 1 1 7 1 49
# 2 1 7 4 36
# 3 1 7 9 25
# 4 1 7 16 16
# 5 2 6 0 48
# 6 2 6 3 35
# 7 2 6 8 24
# 8 2 6 15 15
# 9 4 4 NA NA
Run Code Online (Sandbox Code Playgroud)
如何获得与使用 相同的结果square_it
,但从使用 的矢量化函数获得case_when
?
您需要确保每次调用该函数时都创建 1 行 tibble,然后对其进行矢量化。
无论您是否有rowwise
团体,这都有效。
您可以通过switch
包裹来做到这一点map2
:
这是一个代表:
library(tidyverse)
tibTest <- tibble(argX = 1:4, argY = 7:4)
square_it <- function(xx, yy) {
map2(xx, yy, function(x, y){
switch(which(c(x >= 4,
x == 3,
x == 2,
x < 4 & x != 3 & x != 2)),
tibble(x = NA, y = NA),
tibble(x = as.integer(), y = as.integer()),
tibble(x = x^2 - 1, y = y^2 -1),
tibble(x = x^2, y = y^2))})
}
tibTest %>% mutate(sq = square_it(argX, argY)) %>% unnest(cols = sq)
#> # A tibble: 3 x 4
#> argX argY x y
#> <int> <int> <dbl> <dbl>
#> 1 1 7 1 49
#> 2 2 6 3 35
#> 3 4 4 NA NA
Run Code Online (Sandbox Code Playgroud)
由reprex 包(v0.3.0)于 2020-05-16 创建