dplyr的case_when函数出现错误:'names'属性[1]的长度必须与向量[0]的长度相同。

15

我在 dplyr 链中运行以下的 case_when

open_flag = case_when (
  open_flag == 0 & (click_flag > 0 | mirror_flag > 0) ~ 1,
  TRUE ~ open
)

以上所有变量均为 int 类型。然而,我收到了这个错误信息:

在 names(message) <- vtmp: ! 'names' attribute [1] must be the same length as the vector [0] 中出现错误。

我找到了这篇文章(dplyr::case_when() inexplicably returns names(message) <- `*vtmp*` error),发现了这个问题。尽管我并不完全理解这个问题,所以我未能为我的 case_when() 应用解决方案!

注意:我可以通过使用 ifelse() 来解决这个问题,但我真的很想知道如何为 case_when() 语句解决它!


2
你能展示一个小的可重现的例子吗?错误信息显示所有这些参数可能长度不同。这些列在数据中吗?例如open_flag,open,click_flag,mirror_flag等? - akrun
1
应该是 TRUE ~ open_flag 吗? - langtang
如果您提供一个简单的可重现示例,包括样本输入和期望输出,那么我们就更容易帮助您测试和验证可能的解决方案。那个错误似乎与您展示的代码没有关系,如果我们能够重新创建它以查看发生了什么,那将非常有帮助。 - MrFlick
2个回答

37

我也收到了相同的错误信息,花了15分钟才理解问题所在。原因是试图将integernumeric类型合并。以下是一个可重现的示例:

这不是一个非常有用的错误信息 :(

library(tidyverse)

# sample data
df <- tibble(
  int_var  = 1:10,
  real_var = as.numeric(1:10),
  use_int  = c(rep(TRUE, 5), rep(FALSE, 5))
)

# error
df %>%
  mutate(
    new_var = case_when(
      use_int ~ int_var,
      TRUE    ~ real_var
    )
  )
#> Error in `mutate()`:
#> ! Problem while computing `new_var = case_when(use_int ~ int_var, TRUE ~
#>   real_var)`.
#> Caused by error in `` names(message) <- `*vtmp*` ``:
#> ! 'names' attribute [1] must be the same length as the vector [0]

# fixed
df %>%
  mutate(
    new_var = case_when(
      use_int ~ as.numeric(int_var),  # coerce to numeric
      TRUE    ~ real_var
    )
  )
#> # A tibble: 10 × 4
#>    int_var real_var use_int new_var
#>      <int>    <dbl> <lgl>     <dbl>
#>  1       1        1 TRUE          1
#>  2       2        2 TRUE          2
#>  3       3        3 TRUE          3
#>  4       4        4 TRUE          4
#>  5       5        5 TRUE          5
#>  6       6        6 FALSE         6
#>  7       7        7 FALSE         7
#>  8       8        8 FALSE         8
#>  9       9        9 FALSE         9
#> 10      10       10 FALSE        10

2022年8月3日,使用reprex软件包 (v2.0.1)创建


这真是太有帮助了,我之前完全被这个错误难住了! - leslie roberson
1
当我想让我的一个案例为字符变量生成NA时,遇到了类似的问题:需要使用NA_character_ - Mark Davies
他们的编程真是太愚蠢了。我在尝试用字符串填充一些缺失的因子水平时也遇到了这个问题。错误信息说了一些关于长度的事情,这非常具有误导性。 - CoderGuy123
2
与@MarkDavies类似,需要将其设置为NA_real_而不仅仅是NA,以便为数字变量生成一个〜NA赋值。 - bmacwilliams
非常感谢!我在那个问题上卡了两个小时... 不过这种行为相当奇怪。 - Robin.N.

0

我相信你需要将 TRUE ~ open 更正为 TRUE ~ open_flag

错误:

d %>% 
  mutate(
    open_flag = case_when(
      open_flag == 0 & (click_flag > 0 | mirror_flag > 0) ~ 1,
      TRUE ~ open
    )
  )

Error in `mutate()`:
! Problem while computing `open_flag = case_when(...)`.
Caused by error in `` names(message) <- `*vtmp*` ``:
! 'names' attribute [1] must be the same length as the vector [0]
Run `rlang::last_error()` to see where the error occurred.

正确:

d %>% 
  mutate(
    open_flag = case_when(
      open_flag == 0 & (click_flag > 0 | mirror_flag > 0) ~ 1,
      TRUE ~ open_flag
  )
)

  open_flag click_flag mirror_flag
1         0         -1           0
2         2          0           0
3         1          1           3

输入:

d <- data.frame(
  open_flag = c(0, 2, 0),
  click_flag = c(-1, 0, 1),
  mirror_flag = c(0, 0, 3)
)

1
谢谢您的回答。事实上,我已经发现并在我的代码中修复了这个问题,但我仍然得到了相同的错误。无论如何,鉴于提供的问题代码,我将把这个问题标记为答案。如果我能够模拟一个类似于我正在处理的机密数据集,我将发布另一个关于持久性问题的问题。 - Sal
6
不行。即使存在open列,如果每个“case”的响应不是相同的类别(例如字符与因子),仍然会出现错误。 - Kim
这是真的,错误发生的原因是open是一个函数类,而open_flag是一个整型。问题在于在case_when()中使用了open而不是open_flag,这是错误的(正如OP所指出的,所有变量都是相同类型)。 - langtang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接