-2

Trying to implement a solution to an earlier post, and have encountered behavior that I do not understand using functions.

I have a dataset of the form:

tC <- textConnection("Col1  Col2    Col3
yes no  no
yes no  yes
yes yes yes");
data1 <- read.table(header=TRUE, tC);
close.connection(tC);
rm(tC);
data1["Col4"] <- NA;

Now I would like to use a function to (for now) arbitrarily replace the entries in column 4:

updateRow <- function(rIndex) {  
    data1[rIndex, 4] <- 1
data1 <- return(data1)
}

However, when I apply the function, it seems to update as expected (entry of row 1 col4 becomes "1"), but then the dataframe reverts to its original content when I call it:

updateRow(4)
data1

Could someone explain why this is and what I am doing wrong?

marcel
  • 389
  • 1
  • 8
  • 21
  • 1
    I noticed that you did not accept an answer for the last two questions you asked. Please note that if you want to continue receiving help on this site it is courteous to accept the answer that provides you the best solution for your needs. You can accept answers by clicking on the check box under the votes. – dayne Sep 10 '13 at 15:03
  • Thanks. I was not aware of this but have done so. – marcel Sep 11 '13 at 00:02

4 Answers4

3

You have a lot of syntax errors in your code. I think you actually mean to call updateRow(1). This is another solution that does not require you to redefine your data frame. Your problem comes from not understanding R environments. This post helped me a lot.

updateRow <- function(rIndex) {  
  data1[rIndex, 4] <<- 1
}

> data1
  Col1 Col2 Col3 Col4
1  yes   no   no   NA
2  yes   no  yes   NA
3  yes  yes  yes   NA

> updateRow(1)
> data1
  Col1 Col2 Col3 Col4
1  yes   no   no    1
2  yes   no  yes   NA
3  yes  yes  yes   NA

> updateRow(4)
> data1
  Col1 Col2 Col3 Col4
1  yes   no   no    1
2  yes   no  yes   NA
3  yes  yes  yes   NA
4 <NA> <NA> <NA>    1
dayne
  • 7,504
  • 6
  • 38
  • 56
2

You can use a combination of eval.parent and bquote:

updateRow <- function(rIndex) eval.parent(bquote(data1[.(rIndex), 4] <- 1))

Result:

> updateRow(4)
> data1
  Col1 Col2 Col3 V4
1  yes   no   no NA
2  yes   no  yes NA
3  yes  yes  yes NA
4 <NA> <NA> <NA>  1
Ferdinand.kraft
  • 12,579
  • 10
  • 47
  • 69
  • This answer reminded me of an earlier question that asked for an `inc` or "++" function: http://stackoverflow.com/questions/7768686/r-self-reference/7769296#7769296 . Effectively sidestepping the usual R paradigm. – IRTFM Sep 10 '13 at 16:17
1

Your syntax is wrong if your purpose is to update data1. You should use

updateRow <- function(rIndex) {  
    data1[rIndex, 4] <- 1
    return(data1)
}
data1<-updateRow(4)

This should do it. It will update row 4 and column 4 and set the value to 1.

If you want to skip the last assignment you can define the function as

updateRow <- function(rIndex) {  
    data1[rIndex, 4] <<- 1
}
updateRow(4)

which will also update row 4 and column 4 to the value 1. This is the same solution as dayne has in his answer.

Dr. Mike
  • 2,451
  • 4
  • 24
  • 36
  • @dayne I didn't see your answer before. I just iteratively improved my own answer. If you feel violated I can of course remove it. I have added you name to my answer. – Dr. Mike Sep 10 '13 at 15:05
  • Thanks, this works great. Also my introduction to "<<-", which I have not seen before. – marcel Sep 11 '13 at 00:36
  • 2
    @marcel - to quote `fortune(174)` "I wish `<<-` had never been invented, as it makes an esoteric and dangerous feature of the language *seem* normal and reasonable. If you want to dumb down R/S into a macro language, this is the operator for you". - Bill Venables (2001). It's not an oft-promoted function in the R world. – thelatemail Sep 11 '13 at 06:45
  • I would have to agree with @thelatemail on this. The `<<-` operator is dangerous to use as it operates on entities it has no explicit knowledge of. – Dr. Mike Sep 11 '13 at 09:39
0

You are not assigning anything to dataRow, and thus data1 inside updateRow is not "exported" out of the function, i.e., you never actually update data1. You should say data1 <- updateRow(4)

Doctor Dan
  • 771
  • 4
  • 11