0

my problem is, that some code gets executed outside a function, but not in it. In my example, the content of certain cells should be transferred from the input table to the output table. In case of removal or adding of rows/cols I don't access the cells by their index (e.g input[3,4]), but by application of a condition (e.g. input[(which(input$code=="A1")),(which(colnames(input)=="kg"))].

so here's a minimized version of my data:

input<-data.frame(animal=c("cat","dog","mouse","deer","lion"),
                  m=c(0.5,1,0.1,1.5,3),
                  kg=c(5,20,0.2,50,100),
                  code=c("A4","A5","A3","A1","A2"))
output<-data.frame(code=c("A1","A2","A3","A4","A5"),
                  kg=numeric(5))

execution outside the function, that works (the content of a cell of the input table should be copied to a suitable one in the output table):

row_out<-which(output$code=="A1")
col_out<-which(colnames(output)=="kg")
row_in<-which(input$code=="A1")
col_in<-which(colnames(input)=="kg")

output[row_out,col_out]<-input[row_in,col_in]

and the function, that contains the same code, which worked outside, except for the substitution of the quoted code expression for a function argument (codeexpression):

fun_transfer<-function(codeexpression){
  row_out<-which(output$code==codeexpression)
  col_out<-which(colnames(output)=="kg")
  row_in<-which(input$code==codeexpression)
  col_in<-which(colnames(input)=="kg")
  output[row_out,col_out]<-input[row_in,col_in]
}

Problem: now the execution of

fun_transfer("A4")

does not lead to an error, nor to a result in the output table.

Why doesn't this function work or rather what does it do? Is there a problem with quotation marks? any help would be appreciated thanks, Michel

michel
  • 33
  • 6
  • 1
    This should answer your question https://stackoverflow.com/questions/3969852/update-data-frame-via-function-doesnt-work – Ronak Shah Aug 02 '21 at 14:10
  • 1
    I think @RonakShah's link will start you down the right path. A very key sentence in that answer is *"it's good form to pass all necessary objects as arguments to the function"*. I might extend it a little to say *"it's poor form to use objects not explicitly passed to the function"*, for several reasons but mostly centered on reduced reproducibility and difficult in troubleshooting. – r2evans Aug 02 '21 at 14:33
  • thanks RonakShah and r2evans, your hints might solve my question. First tries seemed to be promising. – michel Aug 02 '21 at 14:58

1 Answers1

0

In the best case, data enters a function as argument and leaves it as a return value.

Outside of a function

output[row_out,col_out] <- input[row_in,col_in]

changes the existing data.frame. You can (or better: should) not change some variable outside the function from within the function.

Just end your function with a return statement to return the changed dataframe to the caller

Edit

It appears as if what you try to write is a lesser version of merge. If the following answers your question it will probably be more concise, faster and more idiomatic:

input<-data.frame(animal=c("cat","dog","mouse","deer","lion"),
                  m=c(0.5,1,0.1,1.5,3),
                  kg=c(5,20,0.2,50,100),
                  code=c("A4","A5","A3","A1","A2"))
output<-data.frame(code=c("A1","A2","A3","A4","A5"))


output <- merge(output, input[, c("code", "kg")], by = "code", 
                all.x = TRUE, all.y = FALSE)
print(output)
Bernhard
  • 4,272
  • 1
  • 13
  • 23
  • thanks Bernard! the return statement works, and now I have to deal with applying the function several times to copy all cells – michel Aug 02 '21 at 14:54
  • @michel please check whether the inbuild function `merge` suits your needs. If not, please explain more detailed what exactly needs to be done. – Bernhard Aug 03 '21 at 17:12