0

I'm new to R language so I may have missed out something... I'm trying to run it in a for loop.

Assuming i<-1, and parti1 is a table.(dataframe)

partin<-paste("parti", i, sep = "")
eval(parse(text = partin))["Time"] <- "1"

However, it gives an error of

Error in file(filename, "r") : cannot open the connection In addition: Warning message: In file(filename, "r") : cannot open file 'parti1': No such file or directory

But it gives no error when I do this

eval(parse(text = partin))["Time"] 

Or this.

parti1["Time"]<-"1"

Or this.

parti1<-eval(parse(text = paste("time", i, sep = "")))

I'm not sure if I'm doing anything wrong or if there's anything I'm missing. Should I not use eval(parse(mystring))? If so, what should I use instead?

Update:

Input: Old table:

Name Gender Hobbies


name    F   singing 

Output: New table:

Name Gender Hobbies Time


name    F   singing 10:15
  • hmm... I'm bring in many other variable in with the loop hence I'm using a loop. I'm trying to create a new column to the table by using 'eval(parse(text = partin))["Time"] <- "1"' but it gives me the error. Any idea...? – lovelynyaa Oct 04 '14 at 07:01
  • You could use `eval(parse(`, but there are better methods to do the problem unless I am completely mistaken :-) – akrun Oct 04 '14 at 07:05
  • But I tried using the `eval(parse(` but I got the error in the question... – lovelynyaa Oct 04 '14 at 07:13
  • Also `library(fortunes); fortune(106) If the answer is parse() you should usually rethink the question. -- Thomas Lumley R-help (February 2005)` – akrun Oct 04 '14 at 08:16
  • It works with your example data. Check the update – akrun Oct 04 '14 at 08:52

1 Answers1

0

If I understand your question:

Created three parti datasets

 parti1 <- as.data.frame(matrix(5:25, ncol=3, dimnames=list(NULL, c("Col1", "Col2", "Time"))))
 parti2 <- as.data.frame(matrix(1:15, ncol=3, dimnames=list(NULL, c("Col1", "Col2", "Time"))))
 parti3 <- as.data.frame(matrix(1:15, ncol=3, dimnames=list(NULL, c("Col1", "Col2", "Time"))))

Used ls and mget to get the values of the datasets

For example,

ls(pattern="^parti") #gives you the created object names that starts with `parti` in the working environment.
#[1] "parti1" "parti2" "parti3"


lst1 <- mget(ls(pattern="^parti")) #mget will return a list of values of each `parti` object

If you need to change the column Time to 1 for each datasets, there are a couple of ways. The methods below created the columns within the list environment. To change your original datasets, you have to do assign or list2env

Map(function(x, y) {x[,"Time"] <- y; x}, lst1, 1)

Or

 lapply(lst1, function(x) {x$Time <-1; x}) #I am changing the existing `Time` column to 1 by using the assignment operator `<-`.

If you want to create a new column, just do:

 lapply(lst1, function(x) {x$Time1 <-1; x})

Update

If you need to change/create columns in the original dataset,

  partin <- paste0("parti", 1)
  assign(partin, `[[<-`(get(partin),'Time', value=1)) 

The above method take the string i.e. partin as first argument, and uses the replacement function [[<-. Then to get the values of partin use get. The next argument is the column to modify or create ie. Time and assign a value of 1 to that column.

  parti1
  #  Col1 Col2 Time
  #1    5   12    1
  #2    6   13    1
  #3    7   14    1
  #4    8   15    1
  #5    9   16    1
  #6   10   17    1
  #7   11   18    1

For multiple datasets, to change/create a existing column/new column, you could use a for loop with assign or use list2env

  partin1 <- paste0("parti", 1:3)
  for(i in seq_along(partin1)){
  assign(partin1[i], `[[<-`(get(partin1[i]), 'Time1', value=5)) #creating a new column
   }

  parti2
  #  Col1 Col2 Time Time1
  #1    1    6   11     5
  #2    2    7   12     5
  #3    3    8   13     5
  #4    4    9   14     5
  #5    5   10   15     5

This could be also done using list2env

  list2env(lapply(mget(partin1), 
         function(x) {x$Time2 <- 10 ;x}), envir=.GlobalEnv)

But, I would suggest doing the analysis in a list rather than creating objects.

Update2

Method using eval(parse

 partin <- paste0("parti", 1)
 toAssign <- paste0(partin, "[,'Time3']")
 str1 <- paste0(toAssign, "<-", 15)
 eval(parse(text=str1))
 parti1
 #  Col1 Col2 Time Time3
 #1    5   12   19    15
 #2    6   13   20    15
 #3    7   14   21    15
 #4    8   15   22    15
 #5    9   16   23    15
 #6   10   17   24    15
 #7   11   18   25    15

Using the example dataset provided

 toAssign <- paste0("Oldtbl", "[, 'Time']")
 str1 <- paste0(toAssign, "<-", "'10:15'")
 eval(parse(text=str1))

 Oldtbl
 # Name Gender Hobbies  Time
 #1 name  FALSE singing 10:15

data

Oldtbl <- structure(list(Name = "name", Gender = FALSE, Hobbies = "singing", 
Time = "10:15"), row.names = c(NA, -1L), .Names = c("Name", 
"Gender", "Hobbies", "Time"), class = "data.frame")
akrun
  • 874,273
  • 37
  • 540
  • 662
  • not that much on how to put it in but more of how to call in the name. since the i can be any value and I don't know it, I can't call the name by parti1 so I need to use `eval(parse(text = partin))["Time"]` or any other methods. sorry... I'm really new to r, so maybe you could give a bit more explanation? is there no way to just add a new column without specifying the number of columns it already have? the one I saw before was `table_name["new_ column_name"]<-value`. – lovelynyaa Oct 04 '14 at 07:12
  • @lovelynyaa `table_name["new_column..` is one to create a new column in a single dataset. By using `lapply`, I am doing the same, but that columns will not be available in the global space. To do that, you can do `assign`, or `list2env` – akrun Oct 04 '14 at 07:54
  • Yea. I'm trying to create a new column in a single data set. I was able to do it if I didn't use eval(parse( as the table name. But with it, it causes an error. – lovelynyaa Oct 04 '14 at 08:02
  • @lovelynyaa Does that mean that you don't need assign? Why do you want to use `eval(parse(`? It is often not recommended – akrun Oct 04 '14 at 08:03
  • Hmmm... Yea I do not need assign. Umm... I use eval(parse( as I do not know of others that I could use... I tried do.call before but it doesn't seem to work. Maybe because I need another library. Is there any others that can do the same? Because from what I've seen, eval(parse( seems to be the only one that worked for me. – lovelynyaa Oct 04 '14 at 08:06
  • @lovelynyaa `eval(parse(` is the last method I would try. Again, without any reproducible example or expected output (though I requested repeatedly), it is hard to tell. – akrun Oct 04 '14 at 08:13
  • Updated with the input and output would it help? – lovelynyaa Oct 04 '14 at 08:40
  • Oooh... Ok so to put it as a string and run it using eval(parse(? Thanks! I'll try it out later to see if it works. – lovelynyaa Oct 04 '14 at 08:45