使用 dplyr 时 if_else(返回太长的向量)和 case_when 的区别

问题描述 投票:0回答:1

这是一个完整构建的示例。这只是为了理解概念上的差异。

我正在运行这段代码

library(palmerpenguins)
penguins %>% 
  group_by(species) %>% 
  filter(
    if_else(
      species == "Adelie", 
      if_else(
        n_distinct(island) > 1,
        row_number() == 1,
        row_number() == 2
      ),
      row_number() %in% 1:2
    ))

认为当物种是 Adelie 并且该物种中只有一个岛时,它将返回第一行,否则返回第二行。如果物种不是 Adelie,则返回前两行。但是我收到这个错误:

Error in `filter()`:
ℹ In argument: `if_else(...)`.
ℹ In group 1: `species = Adelie`.
Caused by error in `if_else()`:
! `true` must have size 1, not size 152.

我完全不明白,因为

row_number() == 1
按行返回
FALSE
TRUE
不是吗?

我知道我用

case_when
运行它,如下所示:

penguins %>%
  group_by(species) %>%
  filter(case_when(
    species == "Adelie" & n_distinct(island) > 1 ~ row_number() == 1,
    species == "Adelie" ~ row_number() == 2, 
    .default = row_number() %in% 1:2 
  ))

而且它有效。我以为

if_else
case_when
是矢量化的。但我想我在这里缺少一些基本的东西。对于任何提示我都会非常有帮助。

r dplyr tidyverse case
1个回答
0
投票

true=
false=
if_else
腿将被回收到
condition
参数的长度,但
condition
不会被回收到
true
false
的长度。 回收也意味着更长的时间。 回收不会让东西变得更短。

condition
以及
true
false
腿在回收后必须具有相同的长度,因为
n_distinct(island) > 1
条件的长度为1,不会被回收,而
true
false
腿的长度> 1 我们有一个错误。

我们可以用这个替换

if_else
,我们已经使用
rep
来自行回收条件到腿的长度:

ifelse(rep(n_distinct(island) > 1, n()), row_number() == 1, row_number() == 2)

但我们真正想要的是

if
而不是
if_else

if (n_distinct(island) > 1) row_number() == 1 else row_number() == 2
© www.soinside.com 2019 - 2024. All rights reserved.