Leandro
Leandro

Reputation: 178

Case statement to replace ifelse in dealing with vectors

In using the QCA package, we usually employ ifelse to replace dataset columns with dichotomized values. But I find it ugly to have to use nested ifelses when dealing with fuzzy sets.

Is there a way to use a case statement instead? switch is only for control flow, and does not deal with vectors.

For example:

DDDfz $VIES <- ifelse (DDD $vies == "p", 1, 0)

is OK, but

DDDfz $TIPO <- switch (DDD $tipo, "PD", 0, "PL", 0.5, "MP", 1)
    Error in switch(DDD$tipo, "PD", 0, "PL", 0.5, "MP", 1) : 
    EXPR deve ser um vetor de comprimento 1

Upvotes: 1

Views: 1425

Answers (3)

Gregory Demin
Gregory Demin

Reputation: 4836

#data example
TIPO = c("PD", "PL",  "MP", "PL",  "MP")

# here we create dictionary 
dict = c("PD" = 0, "PL" = 0.5, "MP" = 1)
# further we match dictionary with original values 
recoded_TIPO = dict[TIPO]

# result
recoded_TIPO

Upvotes: 2

Konrad Rudolph
Konrad Rudolph

Reputation: 545528

The R switch function is unfortunately quite limited in its usefulness. The ‹dplyr› package has a nice pattern matching function that’s more powerful:

result = case_when(
    x == 'PD' ~ 0,
    x == 'PL' ~ 0.5,
    x == 'MP' ~ 1
)

In this particular case, the other solutions (using factors or a vector) are more concise and also more efficient. But case_when is more powerful in general.

Upvotes: 1

Roland
Roland

Reputation: 132676

switch is not vectorized and can't be used here. R offers the factor data class for tasks like this.

factor(c(0, 0.5, 1), levels = c(0, 0.5, 1), 
                     labels = c("PD", "PL", "MP"))
#[1] PD PL MP
#Levels: PD PL MP

You also don't need ifelse in your first example. You can simply do as.integer(DDD$vies == "p").

PS: A space in front of $ is a weird code style.

Upvotes: 5

Related Questions