I want to make a function to change name of a vector when it matches another vector. When I write it as a for loop it works, but I want to put it in a function, then it doesnt work, what am I doing wrong? Thanks!
In a for loop:
df <- 1:5
df2 <- data.frame(id=3:7, name=LETTERS[1:5])
for(i in 1:length(df)) {
for(j in 1:nrow(df2)){
if(df[i]==df2$id[j]){
df[i] <- df2$name[j]
}
}
}
df
#> [1] "1" "2" "A" "B" "C"
I want it in a function, it doesnt work:
match <- function(df,df2){
for(i in 1:length(df)) {
for(j in 1:nrow(df2)){
if(df[i]==df2$id[j]){
df[i] <- df2$name[j]
}
}
}
}
df <- match(df,df2)
df
#> NULL
CodePudding user response:
You forgot to return the df inside the function.
match <- function(df,df2){
for(i in 1:length(df)) {
for(j in 1:nrow(df2)){
if(df[i]==df2$id[j]){
df[i] <- df2$name[j]
}
}
}
df
}
df <- 1:5
df2 <-data.frame(id=3:7, name=LETTERS[1:5])
df <- match(df, df2)
df
#> [1] "1" "2" "A" "B" "C"
Created on 2021-11-18 by the reprex package (v2.0.1)
CodePudding user response:
As R is a vectorized language, loops are not necessary here. What about using the buil-in match
:
tmp <- df2$name[match(df, df2$id)]
df <- ifelse(is.na(tmp), df, tmp)
df
# [1] "1" "2" "A" "B" "C"
This can of course be wrapped by a function.
As an alternative, one can also use a "join" function, e.g. left_join
from package dplyr.