Trucos para gestionar la memoria disponible en una sesión de R

Resuelto Dirk is no longer here asked hace 54 años • 28 respuestas

¿Qué trucos utiliza la gente para gestionar la memoria disponible de una sesión interactiva de R? Utilizo las siguientes funciones [basadas en publicaciones de Petr Pikal y David Hinds en la lista de ayuda de r en 2004] para enumerar (y/o ordenar) los objetos más grandes y, ocasionalmente, rm()algunos de ellos. Pero, con diferencia, la solución más eficaz fue... ejecutarlo en Linux de 64 bits con amplia memoria.

¿Algún otro buen truco que la gente quiera compartir? Uno por publicación, por favor.

# improved list of objects
.ls.objects <- function (pos = 1, pattern, order.by,
                        decreasing=FALSE, head=FALSE, n=5) {
    napply <- function(names, fn) sapply(names, function(x)
                                         fn(get(x, pos = pos)))
    names <- ls(pos = pos, pattern = pattern)
    obj.class <- napply(names, function(x) as.character(class(x))[1])
    obj.mode <- napply(names, mode)
    obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
    obj.size <- napply(names, object.size)
    obj.dim <- t(napply(names, function(x)
                        as.numeric(dim(x))[1:2]))
    vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
    obj.dim[vec, 1] <- napply(names, length)[vec]
    out <- data.frame(obj.type, obj.size, obj.dim)
    names(out) <- c("Type", "Size", "Rows", "Columns")
    if (!missing(order.by))
        out <- out[order(out[[order.by]], decreasing=decreasing), ]
    if (head)
        out <- head(out, n)
    out
}
# shorthand
lsos <- function(..., n=10) {
    .ls.objects(..., order.by="Size", decreasing=TRUE, head=TRUE, n=n)
}
Dirk is no longer here avatar Jan 01 '70 08:01 Dirk is no longer here
Aceptado

Asegúrese de registrar su trabajo en un guión reproducible. De vez en cuando, vuelva a abrir R y luego source()su script. Limpiarás todo lo que ya no uses y, como beneficio adicional, habrás probado tu código.

hadley avatar Aug 31 '2009 16:08 hadley

Yo uso el paquete data.table . Con su :=operador podrás:

  • Agregar columnas por referencia
  • Modificar subconjuntos de columnas existentes por referencia y por grupo por referencia
  • Eliminar columnas por referencia

Ninguna de estas operaciones copia el (potencialmente grande) data.tableen absoluto, ni siquiera una vez.

  • La agregación también es particularmente rápida porque data.tableutiliza mucha menos memoria de trabajo.

Enlaces relacionados :

  • Noticias de data.table, presentación de London R, 2012
  • ¿ Cuándo debo utilizar el :=operador en data.table?
Matt Dowle avatar Aug 10 '2012 10:08 Matt Dowle

¡Vi esto en una publicación de Twitter y creo que es una función increíble de Dirk! Siguiendo con la respuesta de JD Long , haría esto para una lectura fácil de usar:

# improved list of objects
.ls.objects <- function (pos = 1, pattern, order.by,
                        decreasing=FALSE, head=FALSE, n=5) {
    napply <- function(names, fn) sapply(names, function(x)
                                         fn(get(x, pos = pos)))
    names <- ls(pos = pos, pattern = pattern)
    obj.class <- napply(names, function(x) as.character(class(x))[1])
    obj.mode <- napply(names, mode)
    obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
    obj.prettysize <- napply(names, function(x) {
                           format(utils::object.size(x), units = "auto") })
    obj.size <- napply(names, object.size)
    obj.dim <- t(napply(names, function(x)
                        as.numeric(dim(x))[1:2]))
    vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
    obj.dim[vec, 1] <- napply(names, length)[vec]
    out <- data.frame(obj.type, obj.size, obj.prettysize, obj.dim)
    names(out) <- c("Type", "Size", "PrettySize", "Length/Rows", "Columns")
    if (!missing(order.by))
        out <- out[order(out[[order.by]], decreasing=decreasing), ]
    if (head)
        out <- head(out, n)
    out
}
    
# shorthand
lsos <- function(..., n=10) {
    .ls.objects(..., order.by="Size", decreasing=TRUE, head=TRUE, n=n)
}

lsos()

Lo que resulta en algo como lo siguiente:

                      Type   Size PrettySize Length/Rows Columns
pca.res                 PCA 790128   771.6 Kb          7      NA
DF               data.frame 271040   264.7 Kb        669      50
factor.AgeGender   factanal  12888    12.6 Kb         12      NA
dates            data.frame   9016     8.8 Kb        669       2
sd.                 numeric   3808     3.7 Kb         51      NA
napply             function   2256     2.2 Kb         NA      NA
lsos               function   1944     1.9 Kb         NA      NA
load               loadings   1768     1.7 Kb         12       2
ind.sup             integer    448  448 bytes        102      NA
x                 character     96   96 bytes          1      NA

NOTA: La parte principal que agregué fue (nuevamente, adaptada de la respuesta de JD):

obj.prettysize <- napply(names, function(x) {
                           print(object.size(x), units = "auto") })
Tony Breyal avatar Jan 28 '2011 11:01 Tony Breyal

Hago un uso agresivo del subsetparámetro seleccionando solo las variables requeridas cuando paso marcos de datos al data=argumento de las funciones de regresión. Resulta en algunos errores si olvido agregar variables tanto a la fórmula como al select=vector, pero aún así ahorra mucho tiempo debido a la disminución de la copia de objetos y reduce significativamente el uso de memoria. Digamos que tengo 4 millones de registros con 110 variables (y los tengo). Ejemplo:

# library(rms); library(Hmisc) for the cph,and rcs functions
Mayo.PrCr.rbc.mdl <- 
cph(formula = Surv(surv.yr, death) ~ age + Sex + nsmkr + rcs(Mayo, 4) + 
                                     rcs(PrCr.rat, 3) +  rbc.cat * Sex, 
     data = subset(set1HLI,  gdlab2 & HIVfinal == "Negative", 
                           select = c("surv.yr", "death", "PrCr.rat", "Mayo", 
                                      "age", "Sex", "nsmkr", "rbc.cat")
   )            )

A modo de establecer el contexto y la estrategia: la gdlab2variable es un vector lógico que se construyó para sujetos en un conjunto de datos que tenía todos los valores normales o casi normales para un conjunto de pruebas de laboratorio y HIVfinalera un vector de caracteres que resumía las pruebas preliminares y confirmatorias del VIH. .

IRTFM avatar Dec 05 '2010 18:12 IRTFM

Me encanta el script .ls.objects() de Dirk, pero seguí entrecerrando los ojos para contar caracteres en la columna de tamaño. Así que hice algunos trucos feos para que estuviera presente con un formato bonito para el tamaño:

.ls.objects <- function (pos = 1, pattern, order.by,
                        decreasing=FALSE, head=FALSE, n=5) {
    napply <- function(names, fn) sapply(names, function(x)
                                         fn(get(x, pos = pos)))
    names <- ls(pos = pos, pattern = pattern)
    obj.class <- napply(names, function(x) as.character(class(x))[1])
    obj.mode <- napply(names, mode)
    obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
    obj.size <- napply(names, object.size)
    obj.prettysize <- sapply(obj.size, function(r) prettyNum(r, big.mark = ",") )
    obj.dim <- t(napply(names, function(x)
                        as.numeric(dim(x))[1:2]))
    vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
    obj.dim[vec, 1] <- napply(names, length)[vec]
    out <- data.frame(obj.type, obj.size,obj.prettysize, obj.dim)
    names(out) <- c("Type", "Size", "PrettySize", "Rows", "Columns")
    if (!missing(order.by))
        out <- out[order(out[[order.by]], decreasing=decreasing), ]
        out <- out[c("Type", "PrettySize", "Rows", "Columns")]
        names(out) <- c("Type", "Size", "Rows", "Columns")
    if (head)
        out <- head(out, n)
    out
}
JD Long avatar Mar 09 '2010 15:03 JD Long