15

I am running the following case_when inside a dplyr chain:

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

All variables above are of type int. However, I get back this message:

Caused by error in names(message) <- vtmp: ! 'names' attribute [1] must be the same length as the vector [0]

I have found this post (dplyr::case_when() inexplicably returns names(message) <- `*vtmp*` error) that identified the issue. I don't fully understand the issue, and so I failed to apply a solution for my case_when() above!

Note: I can solve the problem by using ifelse(), but I really wonder how to solve it for the case_when() statement!

Kim
  • 4,080
  • 2
  • 30
  • 51
Sal
  • 331
  • 2
  • 9
  • 2
    Can you show a small reproducible example. The error message says that all those arguments may not have the same length. Are those columns in the data? i.e. open_flag, open, click_flag, mirror_flag etc? – akrun Apr 01 '22 at 21:34
  • 1
    should it be `TRUE ~ open_flag`? – langtang Apr 01 '22 at 21:44
  • It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. That error seems oddly unrelated to the code you've shown. It would be helpful if we could recreate it to see what's going on. – MrFlick Apr 01 '22 at 21:44

2 Answers2

36

I received this same error message and scratched my head for 15 minutes. It was due to trying to combine integer and numeric types. Here is a reproducible example.

It's not a very useful error message :(

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

Created on 2022-08-03 by the reprex package (v2.0.1)

Arthur
  • 1,248
  • 8
  • 14
  • This is so helpful, I was totally stumped on this error! – leslie roberson Aug 18 '22 at 18:38
  • 1
    Had a similar problem when I wanted one of my cases to produce `NA` for a character variable: needed to use `NA_character_` instead – Mark Davies Sep 06 '22 at 19:34
  • Really dumb coding on their part. I also had this issue when trying to fill in some missing factor levels with strings. The error says something about lengths, which is very misleading. – CoderGuy123 Oct 06 '22 at 02:15
  • 1
    Similar to @MarkDavies above, need to set to `NA_real_` not just `NA` to produce an `~ NA` assignment for a numeric variable. – bmacwilliams Oct 27 '22 at 17:03
  • Thank you so much! I am blocked on that for two hours... It is quite strange though for such a behaviour. – Robin.N. Dec 05 '22 at 15:50
0

I believe you need to correct TRUE ~ open to TRUE ~ open_flag:

ERROR:

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.

CORRECT:

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

Input:

d <- data.frame(
  open_flag = c(0, 2, 0),
  click_flag = c(-1, 0, 1),
  mirror_flag = c(0, 0, 3)
)
Kim
  • 4,080
  • 2
  • 30
  • 51
langtang
  • 22,248
  • 1
  • 12
  • 27
  • 1
    Thanks for your answer. In fact, I did find this issue out and fixed it in my code, but I still got the same error. Anyway, I am going to mark this as answer given the provided code in the question. I will post another question regarding the persistent issue if I can mock up a data set similar to the one that I am working on, which is confidential. – Sal Apr 11 '22 at 18:10
  • 6
    No. Even if `open` column exists, the error can happen if the responses to each "case" are not of the same class (e.g., character vs. factor) – Kim Apr 30 '22 at 05:46
  • that's true, and the reason the error occurred is because `open` is of class `function`, while `open_flag` is of type int. (as the OP indicated, all vars of the same type). The problem was the error in using `open`, instead of `open_flag` in the `case_when()` – langtang Aug 18 '22 at 21:20