Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid <<- by using assign

Tags:

r

I have two pieces of code I use often in which I use the <<- to assign to the Global environment from within a function. I know I should be using assign as it gives better control and is more predictable. I am trying to wrap my head around using assign but can't transfer the <<- code to code that uses assign:

A FAKE DATA SET AND THE TWO PIECES OF CODE WITH THE <<-

#CREATE A FAKE DATA SET
df <- data.frame(
    x.2=rnorm(25),
    y.2=rnorm(25),
    g=rep(factor(LETTERS[1:5]), 5)
)
#Use split to make a list of data frames
LIST <- split(df, df$g) #split it into a list of data frames
NAMES <- names(LIST) #save the names of this for later use 
LIST <- lapply(seq_along(LIST), function(x) as.data.frame(LIST[[x]])[, 1:2])

#THE TWO PIECES OF CODE THAT USE <<-
#Use Global Assignment to Change All Variable Names of Data Frames in a List
lapply(seq_along(LIST), function(x) names(LIST[[x]]) <<-
    unlist(strsplit(names(LIST[[x]])[1:length(names(LIST[[x]]))],
    ".", fixed=T))[c(T, F)]
)
LIST

#Rename All the Data Frames in the List Using Global Assignment
lapply(seq_along(LIST), function(x) names(LIST)[[x]] <<- NAMES[x])
LIST

My attempts to use assign:

lapply(seq_along(LIST), function(x) {
    assign(names(LIST[[x]]), 
    unlist(strsplit(names(LIST[[x]])[1:length(names(LIST[[x]]))],
    ".", fixed=T))[c(T, F)],  envir=.GlobalEnv)
    }
)
LIST

lapply(seq_along(LIST), function(x) assign(names(LIST)[[x]], 
    NAMES[x], envir=.GlobalEnv))
LIST

Please help me to do this correctly and axplain what is wrong with my approach. Thank you in advance.

like image 606
Tyler Rinker Avatar asked Mar 16 '12 01:03

Tyler Rinker


1 Answers

I do not understand why you made this task so very complicated. Isn't this just:

LIST <- df[, 1:2]
names(LIST) <- sapply(strsplit(names(LIST), '.', fixed = TRUE), `[`, 1)
LIST <- split(LIST, df$g)

i.e. you want the first 2 columns of df; you want the names before ., and you split the data frame. Reorganize your tasks and you will have a much clearer view of the problem.

BTW, <<- is not necessarily a horrible animal; you can use it very safely by creating the variable name in the top environment, e.g.

x <- 0
f <- function() x <<- 1

The danger only exists if you do not create the variable name at all in any places, so R has to go all the way up to the global environment, and that is usually a very bad practice.

like image 174
Yihui Xie Avatar answered Oct 11 '22 18:10

Yihui Xie