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 apply
ing 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
Options for Deploying R Models in Production
Which Library Could Be Used to Make a Chord Diagram in R
Effectively Debugging Shiny Apps
How to Calculate the 95% Confidence Interval for the Slope in a Linear Regression Model in R
Scatterplot with Alpha Transparent Histograms in R
The Difference Between Domc and Doparallel in R
How and When Should I Use On.Exit
Error: --With-Readline=Yes (Default) and Headers/Libs Are Not Available
How to Combine Row and Column Layout in Flexdashboard
How to Left Align Text in Annotate from Ggplot2
How to Check Existence of an Input Argument for R Functions
What's the Difference Between Facet_Wrap() and Facet_Grid() in Ggplot2
Return Row Number(S) for a Particular Value in a Column in a Dataframe
R- Shiny Webserver on a Local Server
How to Recreate Same Documenttermmatrix with New (Test) Data