返回小标题:如何使用case_when进行矢量化处理? [英] Returning a tibble: how to vectorize with case_when?

查看:105
本文介绍了返回小标题:如何使用case_when进行矢量化处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个返回小标题的函数.它运行正常,但我想对其向量化.

I have a function which returns a tibble. It runs OK, but I want to vectorize it.

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)
  }
}

当我用map2调用它时,它在mutate中可以正常运行,给我想要的结果:

It runs OK in a mutate when I call it with map2, giving me the result I wanted:

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

我对向量进行矢量化的第一次尝试失败了,我明白了为什么-我无法返回tibble的向量.

My first attempt to vectorize it failed, and I can see why - I can't return a vector of tibbles.

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

我的下一次尝试在一个简单的输入上运行正常.我可以返回小标题列表,这就是我想要的unnest

My next attempt runs OK on a simple input. I can return a list of tibbles, and that's what I want for the 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   

但是,当我在mutate中调用它时,它并不能提供与square_it相同的结果.我可以看看是什么 错误的.在xx == 2子句中,xx充当2的原子值. 建立小标题,xx是长度为4的向量.

But when I call it in a mutate, it doesn't give me the result I had with square_it. I can sort of see what's wrong. In the xx == 2 clause, xx acts as an atomic value of 2. But in building the tibble, xx is a length-4 vector.

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

如何获得与square_it相同的结果,但是如何使用case_when从矢量化函数获得结果?

How do I get the same result as I did with square_it, but from a vectorized function using case_when ?

推荐答案

您需要确保在每次调用该函数时都创建一个1行的小标题,然后对其进行矢量化.

You need to ensure you are creating a 1-row tibble with each call of the function, then vectorize that.

无论您是否有rowwise个组,此方法都有效.

This works whether you have rowwise groups or not.

您可以将switch包裹在map2中来完成此操作:

You can do this with switch wrapped in a 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

reprex软件包(v0.3.0)创建于2020-05-16 sup>

Created on 2020-05-16 by the reprex package (v0.3.0)

这篇关于返回小标题:如何使用case_when进行矢量化处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆