HNSKD
HNSKD

Reputation: 1644

How do you use if or ifelse in magrittr %>%?

I would like to apply the function below to the variable names of a dataframe. However for the sake of this question, I will use vector instead (since names(df) is also a vector).

I would like to first, (1) convert all characters in the elements of the vectors to uppercase, next, (2) replace all in-between whitespaces with "_" and finally, (3) padded specific characters to the end of each elements in the vector. This is the function I have written:

pad <- function(vec,pastechr){
  names(vec) <- names(vec) %>%
    toupper() %>%
    str_replace_all(" ", "_") %>%
    if_else(pastechr!="",paste(pastechr,sep="_"),paste0(""))
}

I would like to apply this function on 3 vectors:

vec1 <- c("A","B B","C c")
vec2 <- c("PP p","Q Q","r")
vec3 <- c("x","y z")

Such that, I would paste "123" to vec1, "456" to vec2 at the end of the elements. I do not want to paste anything to vec3. Hence,

pad(vec1,"123")
pad(vec2,"456")
pad(vec3,"")

What I want out of this is:

pad(vec1,"123")
[1] "A_123","B_B_123","C_C_123"

pad(vec2,"456")
[1] "PP_P_456","Q_Q_456","R_456"

pad(vec3,"")
[1] "X","Y_Z"

I obtained an error instead:

Error: condition must be logical

I believe it must have something to do with the if_else line, so I tried:

if(pastechr!="") {paste(pastechr,sep="_")}

and

if_else(pastechr=="",paste0(""),paste(pastechr,sep="_"))

but they wouldn't work. Any advice? Thanks.

Upvotes: 1

Views: 931

Answers (1)

The issue is that the pipe %>% passes your vector (the result of the previous operation) as the first argument to ifelse (not if_else), but ifelse expects a test as the first argument. Also note that the names of your vectors is NULL.

I would use something like:

library(magrittr)
library(stringr)

pad <- function(vec, pastechr){
  vec <- vec %>%
    toupper() %>%
    str_replace_all(" ", "_")
  if (pastechr != "") {
    vec <- paste(vec, pastechr, sep = "_")
  }
  vec
}

vec1 <- c("A","B B","C c")
vec2 <- c("PP p","Q Q","r")
vec3 <- c("x","y z")

pad(vec1,"123")
pad(vec2,"456")
pad(vec3,"")

Which results in:

> pad(vec1,"123")
[1] "A_123"   "B_B_123" "C_C_123"
> pad(vec2,"456")
[1] "PP_P_456" "Q_Q_456"  "R_456"   
> pad(vec3,"")
[1] "X"   "Y_Z"
> 

Upvotes: 2

Related Questions