rfunctionrelationalquotation-marks

code executes outside function, but not inside it


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


Solution

  • 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)