Case_when - why does it work ?

Hi All,

Here is my df:

tmp2 <- structure(list(a = 1:10, b = c(88L, 54L, 17L, 88L, 57L, 52L, 
65L, 12L, 16L, 60L)), row.names = c(NA, -10L), class = c("tbl_df", 
"tbl", "data.frame"))

I want to add new column with mutate() and case_when, provided that: b==17 I will do a*2.
The other values in a and b columns I want to leave intact.

obraz

My code:

tmp2 %>%  dplyr::mutate(new_col = dplyr::case_when(
  b == 17 ~ a*2,
  TRUE ~ b))

is not working.
but this:

tmp2 %>%  dplyr::mutate(new_col = dplyr::case_when(
  b == 17 ~ a*2,
  TRUE ~ b+0))

is working, giving me what I want:
obraz

Why does not "b" working alone in the formula and I must add: "b+0" to make it work ?

Any explanation would be appreciated.

case when does type checking , you are implicitly asking to mix integers with doubles.
You would have received a dplyr error informing you of this

Error: must be a double vector, not an integer vector

here is a solution where you don't require moving away from integers because the arithmetic you are doing is integer based.

  tmp2 %>%  dplyr::mutate(new_col = dplyr::case_when(
    b == 17L ~ a*2L,
    TRUE ~ b))

the uppercase letter L tells R that you want the number interpreted as an integer rather than as a double(floating point number)

2 Likes

Hi @nirgrahamuk, thank you for your reply.

I didn't received an error you pointed out, but a different one:
"Error: Internal error: Trace data is not square."
I don't know what does it mean.

oh, that's stange, perhaps you are using a different version of dplyr than me...
Anyway, I believe my answer stands regardless of my incorrect assumption that the error shown to you would be the same as that shown to me.
If you have other issues in this area, let me know.

I use dplyr 0.8.99.9002 dev version.
Thank you again, your solution works perfectly.
regards,
Andrzej

Hi @nirgrahamuk,
But regarding an error you received:

If I may ask a full question: What must be a double vector, not an integer vector ?

As my dataframe tmp2 consist of an integer vectors:

obraz

Indeed, so adding 17 and multipling by 2 would be assumed to give a double answer, as the default interpretation of 17 and 2 are that they are double's.
This is why i mentioned and showed the use of L

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.