Reputation: 1099
I am trying to use a single conditional statement to update multiple variables in R using dplyr. I have some working code (posted below) however I feel it is very inefficient and am convinced there must be a better way of doing it.
EDIT: Worded description of purpose of the program. The idea is to take the iris dataset an update multiple variables based upon the value of Species, for example if Species == "setosa" then Species = "SETOSA" , Sepal.Length *= 1.5 , Sepal.Width *= 0.5.
library(dplyr)
library(tibble)
multi_update <- function(species , sepal.length , sepal.width , ret){
if ( species == "setosa") {
RET <- list(
Species = "SETOSA",
Sepal.Length = sepal.length * 1.5,
Sepal.Width = sepal.width * 0.5
)
} else if ( species == "versicolor") {
RET <- list(
Species = "VERSI",
Sepal.Length = sepal.length * 2,
Sepal.Width = sepal.width * 1.5
)
} else {
RET <- list(
Species = species,
Sepal.Length = sepal.length ,
Sepal.Width = sepal.width
)
}
return( RET[[ret]] )
}
iris %>%
tbl_df %>%
mutate( Sepal.Length = mapply(multi_update , Species , Sepal.Length , Sepal.Width , "Sepal.Length")) %>%
mutate( Sepal.Width = mapply(multi_update , Species , Sepal.Length , Sepal.Width , "Sepal.Width")) %>%
mutate( Species = mapply(multi_update , Species , Sepal.Length , Sepal.Width , "Species"))
Upvotes: 1
Views: 915
Reputation: 887068
We can create a key val dataset, join
with the original dataset and mutate
the columns
library(dplyr)
kval <- data.frame(Species = c("setosa", "versicolor", "virginica"),
Species.x = c("SETOSA", "VERSI", "virginica"),
Sepal.Length = c(1.5, 2, 1), Sepal.Width = c(0.5, 1.5, 1))
res <- left_join(iris, kval, by = "Species") %>%
mutate(Species = Species.x, Sepal.Length = Sepal.Length.x*Sepal.Length.y,
Sepal.Width = Sepal.Width.x * Sepal.Width.y) %>%
select(-matches("(.x|.y)$"))
head(res)
# Petal.Length Petal.Width Species Sepal.Length Sepal.Width
#1 1.4 0.2 SETOSA 7.65 1.75
#2 1.4 0.2 SETOSA 7.35 1.50
#3 1.3 0.2 SETOSA 7.05 1.60
#4 1.5 0.2 SETOSA 6.90 1.55
#5 1.4 0.2 SETOSA 7.50 1.80
#6 1.7 0.4 SETOSA 8.10 1.95
Upvotes: 4