HannesZ
HannesZ

Reputation: 609

Loop through list of objects and change by reference in data.table

I have a list of data.table objects that all have a similar name and some property that I would like to change on all of them by looping through this list. Let's consider this:

set.seed(999)
GenName_ksio3k_F1 <-data.table(Risknr = runif(10,1000,9999), Code=LETTERS[sample.int(10)], val=rnorm(10));GenName_ksio3k_F1
GenName_kf0bner_F6 <-data.table(Risknr = runif(10,1000,9999), Code=LETTERS[sample.int(10)], val=rnorm(10));GenName_kf0bner_F6
GenName_sjkw_F2 <-data.table(Risknr = runif(10,1000,9999), Code=LETTERS[sample.int(10)], val=rnorm(10));GenName_sjkw_F2

So as suggested by this naming, these objects have similar names which I can capture conveniently in a list via regular expression:

list =  grep("^(GenName_).*(F[0-9])$", ls(), perl=TRUE, value=TRUE);list

Now, what I would like to to do is change the column Risknr to a factor variable on all of these tables. I tried this:

    for(DT in list){
      print(str(eval(parse(text = DT)))) # as a test
      eval(parse(text = DT))$Risikonr <- as.factor(eval(parse(text = DT$Risikonr)
}

accessing the variable seems to work, as printing str for each DT shows. The as.factor-conversion looks wrong and of course does not work. But how to do this?

Upvotes: 1

Views: 927

Answers (1)

akrun
akrun

Reputation: 887158

We can use get to get the value, and if we need to update use assign

for(DT in list){
    assign(DT, value = get(DT)[, Risknr := factor(Risknr)])

}

str(GenName_sjkw_F2)
#Classes ‘data.table’ and 'data.frame':  10 obs. of  3 variables:
# $ Risknr: Factor w/ 10 levels "1899.01318506384",..: 4 9 7 5 1 3 2 10 8 6
# $ Code  : chr  "G" "B" "A" "E" ...
# $ val   : num  -0.1167 -0.645 1.7444 0.3661 -0.0668 ...
# - attr(*, ".internal.selfref")=<externalptr> 
str(GenName_kf0bner_F6)
#Classes ‘data.table’ and 'data.frame':  10 obs. of  3 variables:
# $ Risknr: Factor w/ 10 levels "1497.60077643953",..: 2 10 9 7 6 5 8 4 3 1
# $ Code  : chr  "H" "F" "B" "G" ...
# $ val   : num  2.383 0.601 0.179 1.081 -0.247 ...
# - attr(*, ".internal.selfref")=<externalptr> 

However, it is better to have datasets in a list instead of multiple global objects

Upvotes: 2

Related Questions