Use of Switch() in R to Replace Vector Values

Use of switch() in R to replace vector values

The vectorised form of if is ifelse:

test <- ifelse(test == "He is", 1,
ifelse(test == "She is", 1,
ifelse(test == "He has", 2,
2)))

or

test <- ifelse(test %in% c("He is", "She is"), 1, 2)

switch is basically a way of writing nested if-else tests. You should think of if and switch as control flow statements, not as data transformation operators. You use them to control the execution of an algorithm, eg to test for convergence or to choose which execution path to take. You wouldn't use them to directly manipulate data in most circumstances.

Replace given value in vector

Perhaps replace is what you are looking for:

> x = c(3, 2, 1, 0, 4, 0)
> replace(x, x==0, 1)
[1] 3 2 1 1 4 1

Or, if you don't have x (any specific reason why not?):

replace(c(3, 2, 1, 0, 4, 0), c(3, 2, 1, 0, 4, 0)==0, 1)

Many people are familiar with gsub, so you can also try either of the following:

as.numeric(gsub(0, 1, x))
as.numeric(gsub(0, 1, c(3, 2, 1, 0, 4, 0)))

Update

After reading the comments, perhaps with is an option:

with(data.frame(x = c(3, 2, 1, 0, 4, 0)), replace(x, x == 0, 1))

Apply function with Switch to a vector

Your sapply and for loop constructions don't match, so it makes sense the results aren't the same. In the for loop, the i-th result gets pattern[i] as the 2nd arg. In the sapply version, you pass the whole vector pattern

sapply treats each element of the thing to which you are applying a function one at a time (here, text), but that doesn't apply to arguments in the function you are applying (like pattern)

If you want to iterate through multiple objects, try applying a function to an iteration vector:

sapply(1:12, function(i) get_dates(text[i], pattern[i], pattern_list))

The use of switch is not related, and there's no issue using switch with sapply, e.g.:

my_fun <- function(x) switch(x, a='alpha', b='beta')
sapply(c('a', 'b', 'b'), my_fun)

# a b b
# "alpha" "beta" "beta"

Case statement to replace ifelse in dealing with vectors

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.

Exchange two elements of a vector in one call

You could use replace().

x <- c(9, 6, 3, 4, 2, 1, 5, 7, 8)
replace(x, c(2, 5), x[c(5, 2)])
# [1] 9 2 3 4 6 1 5 7 8

And if you don't even want to assign x, you can use

replace(
c(9, 6, 3, 4, 2, 1, 5, 7, 8),
c(2, 5),
c(9, 6, 3, 4, 2, 1, 5, 7, 8)[c(5, 2)]
)
# [1] 9 2 3 4 6 1 5 7 8

but that's a bit silly. You will probably want x assigned to begin with.

Switch the some of the vector in R

May be this function helps

# @param vec - input vector
# @param n - number of values to replace
# @param n1 - number of unique value threshold
# @return replaced sampled vector

sample_fn <- function(vec, n, n1) {

flag <- TRUE
while(flag) {
# // sample on the positions
pos <- sample(seq_along(vec), n, replace = FALSE)
print(pos)
# // extract the values based on the position index
as <- vec[pos]
# // get the unique values
un1 <- unique(as)
print(un1)
if(length(un1) > n1)
flag <- FALSE
}

# // sample the unique and set it as names of unique
# // use named vector to match and replace
# // assign the output back to the same positions in the vector
vec[pos] <- setNames(sample(un1), un1)[as.character(as)]
vec

}
sample_fn(a, 4, 2)
#[1] 10 1 12 2
#[1] 3 1
#[1] 1 8 4 3
#[1] 1 2
#[1] 7 11 4 12
#[1] 2 3 1
# [1] 1 1 1 2 1 2 3 2 3 3 1 1


How to replace values with a condition in R?

You could use replace() to replace the whole vector with zeros if there are less than 5 positive values in it.

fun <- function(vec) replace(vec, sum(vec > 0) < 5, 0)

sum(vec > 0) < 5 returns a single logical value (either TRUE or FALSE) and it'll recycle to the same length as vec.

Test
dr1 <- c(1,5,3,2,0,2,0,2,0,0,0,2,0)
dr2 <- c(1,0,0,0,0,2,0,0,0,0,0,2,0)

fun(dr1)
# [1] 1 5 3 2 0 2 0 2 0 0 0 2 0

fun(dr2)
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 0

Replace values from a column with value corresponding to vector with matches

dplyr package

You can use recode() in dplyr.

library(dplyr)

df %>%
mutate(roles = recode(roles, "students" = "st", "teacher" = "te"))

If you have assigned roles to variables, then you can take a named vector as input.

roles_complete <- c("students", "teacher")
roles_standard <- c("st", "te")

df %>%
mutate(roles = recode(roles, !!!setNames(roles_standard, roles_complete)))

stringr package

str_replace_all() in stringr also can take a named vector as input.

library(stringr)

df$roles <- str_replace_all(df$roles, setNames(roles_standard, roles_complete))

base solution

df$role <- factor(df$role, labels = c("st", "te"))

Replacing a string with a random number from vector

In your code, you are generating one random value to replace any given grade and that's why you are getting same values.

Here's a simpler way of getting your desired result using base::switch() with sapply and lastly dplyr package to modify all columns ending with "Grade" in one go -

library(dplyr)

replace_grade <- function(g) {
sapply(g, function(a) {
switch(a,
"A" = rnorm(1, 9.45, 0.2),
"B" = rnorm(1, 7.95, 0.2),
"C" = rnorm(1, 6.25, 0.2),
"D" = rnorm(1, 4.75, 0.2),
"F" = rnorm(1, 2, 0.2),
NA_real_
)
})
}

# function output for illustration
replace_grade(g = c("A", "B", "C", "D", "F", NA_character_))
A B C D F <NA>
9.229176 7.830536 6.239904 4.643644 2.146621 NA

# apply function to every column ending with "Grade"
df %>%
mutate_at(vars(ends_with("Grade")), replace_grade)

Student_ID ABC1000_Grade ABC1003_Grade
1 9000006 9.243239 7.946469
2 9000014 9.623083 9.072896
3 9000028 8.308868 6.177990
4 9000045 NA NA
5 9000080 6.336819 NA
6 9000091 NA NA

Data -

df <- read.table(text = "Student_ID ABC1000_Grade   ABC1003_Grade
9000006 A B
9000014 A A
9000028 B C
9000045 <NA> <NA>
9000080 C <NA>
9000091 <NA> <NA>
", header= T, sep = "\t", stringsAsFactors = F)


Related Topics



Leave a reply



Submit