My function won't work like it should

Hello I wrote the following function "REPLACEE" to look for a specific value of a dataframe and change it with the input : Nom.
In the following replex when i run REPLACEE() on my piece of data it return the correct rows but leave the value unchanged when it should be replaced by "xyz". When I do it out of the function the same code work. How can I fix this ?

test<-rbind(c(2             ,  "AISNE"   ,    284           , "Erloy"                 ,  "MARTINACHE", "Francis")
      ,c(2                ,  "AISNE"   ,    284           , "Erloy"                 ,  "LIEZ", "Régine")
      ,c(2                ,  "AISNE"   ,    284           , "Erloy"                 ,  "LAMBERT", "Eric")
      ,c(2                ,  "AISNE"   ,    284           , "Erloy"                 ,  "PRETHOMME", "Raymond")
      ,c(2                ,  "AISNE"   ,    284           , "Erloy"                 ,  "MEURA", "Jacques")
      ,c(2                ,  "AISNE"   ,    284           , "Erloy"                 ,  "CAZE", "Raphaël"))
colnames(test)<-c("Code département"  ,    "Département"   ,        "Code commune"    ,      "Libellé de la commune", "Nom"                  
                  ,"Prénom"  )

REPLACEE <- function(x,y,z,Nom) { 
  res<- which(test[,1]==x&
                test[,3]==y&
                test[,5]==z)
  print(res)
  test[res,5]<-Nom
}
# in function it doesn't work
test[4,5]
#>         Nom 
#> "PRETHOMME"
REPLACEE(2,284,"PRETHOMME","xyz")
#> [1] 4
test[4,5]
#>         Nom 
#> "PRETHOMME"
# out of the function it work
test[4,5]<-"xyz"
test[4,5]
#>   Nom 
#> "xyz"

The first issue I see is that calling the function will actually modify test. I recommend editing the function so it returns a modified version of test but does not modify test itself.

REPLACEE <- function(x,y,z,Nom) { 
  res<- which(test[,1]==x&
                test[,3]==y&
                test[,5]==z)
  print(res)
  result <- test
  result[res,5]<-Nom
  return(result)
}

Second issue is that the numeric columns are being stored as text in the matrix. Because a matrix can only be one type, it cannot store both numeric and text columns. For this purpose, use a data frame instead. If you want a kludge, you can search for the text values like this.

REPLACEE("2","284","PRETHOMME","xyz")

Try changing test[res,5] <- Nom to test[res,5] <<- Nom in the function.

What's happening is that you're trying to modify a global object, test, from within the function. To do that, you need to use the <<- operator.

The alternative, which I think would be considered better coding practice, would be to pass the data frame itself in to the function as an argument and then have the result of the function be the modified data frame. In that case, you would then have a function definition more like this:

REPLACEE  <-  function(df,  x, y , z, Nom){
...
}

And, when you called it, you could have test still operate on itself:

test <- REPLACEE(test, 2, 284, "PRETHOMME", "xyz")

That may cause some performance issues if the data frame is massive (I'm, honestly, not sure), but it would keep you from needing to use the superassignment operator (<<-) and would be easier code for someone else to follow.

Thank you, I didn't know that you couldn't change an object that's not called in the function. For the second issue, I'm actually using a data frame but for the sake of the reprex I did it this way but it worked the same so...
Huge thanks.

Thank you as I said to sir Arthur, I didn't know that function couldn't change something that isn't called.
I didn't know about that super operator that's huge. I'll be the only one to use this code so I'll go with it.
Thanks !!!!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.