2012-03-16 9 views
5

Tengo dos pedazos de código que uso a menudo en los que uso el <<- para asignar al entorno global desde dentro de una función. Sé que debería usar assign ya que da un mejor control y es más predecible. Estoy tratando de envolver mi cabeza alrededor de usar assign pero no puedo transferir el código <<- para asignar el código que utiliza:Cómo evitar << - usando assign

un conjunto de datos falsos y los dos trozos de código con los <<-

#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 

Mis intentos de usar asignar:

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 

Ayúdenme a hacer esto correctamente y expongo lo que está mal con mi enfoque. Gracias de antemano.

+1

nombres de objetos no son un 'nombre' en un entorno, por lo que no puede usar' assign' aquí. – kohske

+0

@kohske Gracias. ¿Puedes dar esa respuesta y la aceptaré? –

Respuesta

2

creo que esto es lo mismo que

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[[x]] 
}) 
LIST 

names(LIST) <- NAMES 
LIST 

o, para usar asigno

assign("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[[x]] 
}), pos=.GlobalEnv) 
+0

Me gusta porque no tengo que usar 'assign' o' << - 'en absoluto. –

3

No entiendo por qué tomó esta tarea de manera muy complicada. No es esto:

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

es decir, desea que el 2 primeras columnas de df; desea los nombres antes del ., y divide el marco de datos. Reorganice sus tareas y tendrá una visión mucho más clara del problema.

BTW, <<- no es necesariamente un animal horrible; puede usarlo de forma muy segura creando el nombre de la variable en el entorno superior, p. ej.

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

El peligro sólo existe si no se crea el nombre de la variable en absoluto en cualquier lugar, por lo que R tiene que ir todo el camino hasta el medio ambiente mundial, y que es por lo general una muy mala práctica.

+0

ignore los datos reproducibles. Fue solo para configurar el problema que surge en mis tareas. Tu solución solo funciona si los datos fueron tan simples y se crearon a partir de un marco de datos y 'split', que no es así. GSee respondió el problema muy bien. +1 para la información sobre la asignación global. –

Cuestiones relacionadas