i need to create a column on a dataframe containing a conditional rule, that will apply only to the values of a singular column called "value".
i have already created the function, however when I try to add it to ne data frame I encounter the following error
fun <- function(x) { #function
if(x < 10) {return ("white")
} else if (x >= 10 && x < 30) {
return ("yellow")
} else if (x >= 30 && x < 50) {
return ("red")
} else {
return ("black")
}
}
#applying as a column on dataframe
dt$newcolumn <- apply(dt, 1, fun(dt$value))
error
Error in if (x < 10) { : missing value where TRUE/FALSE needed
In addition: Warning message:
In if (x < 10) { :
the condition has length > 1 and only the first element will be used
I am prob. doing something wrong when applying the fucntion to the dataframe.
thanks in advance!
CodePudding user response:
As suggested in comments you can use vectorised ifelse or dplyr::case_when which will avoid the use of apply or any other loop. You can directly apply the function to whole column.
library(dplyr)
fun <- function(x) { #function
case_when(x < 10 ~ "white",
between(x, 10, 29) ~ "yellow",
between(x, 30, 49) ~ "red",
TRUE ~ "black")
}
dt <- data.frame(value = c(5, 89, 30, 15))
dt$newcolumn <- fun(dt$value)
dt
# value newcolumn
#1 5 white
#2 89 black
#3 30 red
#4 15 yellow
CodePudding user response:
The logical test in an if statement needs to evaluate to a single TRUE or FALSE, whereas in your case it evaluates to a vector of TRUE and FALSE, which is what causes the error. The vectorized equivalent is ifelse, but that is still not ideal here because you require nested ifelse statements. One can either use switch or case_when for the case of multiple options in the output, but the neatest base R solution here is probably just to use cut:
fun <- function(x) {
as.character(cut(x, c(-Inf, 10, 30, 50, Inf),
c('white', 'yellow', 'red', 'black')))
}
fun(1:100)
#> [1] "white" "white" "white" "white" "white" "white" "white" "white"
#> [9] "white" "white" "yellow" "yellow" "yellow" "yellow" "yellow" "yellow"
#> [17] "yellow" "yellow" "yellow" "yellow" "yellow" "yellow" "yellow" "yellow"
#> [25] "yellow" "yellow" "yellow" "yellow" "yellow" "yellow" "red" "red"
#> [33] "red" "red" "red" "red" "red" "red" "red" "red"
#> [41] "red" "red" "red" "red" "red" "red" "red" "red"
#> [49] "red" "red" "black" "black" "black" "black" "black" "black"
#> [57] "black" "black" "black" "black" "black" "black" "black" "black"
#> [65] "black" "black" "black" "black" "black" "black" "black" "black"
#> [73] "black" "black" "black" "black" "black" "black" "black" "black"
#> [81] "black" "black" "black" "black" "black" "black" "black" "black"
#> [89] "black" "black" "black" "black" "black" "black" "black" "black"
#> [97] "black" "black" "black" "black"
