varias superponer studio lineas histogramas graficos graficas r dataframe subset

superponer - Cómo colocar columnas por nombre en un marco de datos



superponer graficas en r (10)

Aquí hay otra solución que puede ser útil para otros. El siguiente código selecciona un pequeño número de filas y columnas de un conjunto de datos de gran tamaño. Las columnas se seleccionan como en una de las respuestas de juba, excepto que utilizo una función de pegado para seleccionar un conjunto de columnas con nombres que se numeran secuencialmente:

df = read.table(text = " state county city region mmatrix X1 X2 X3 A1 A2 A3 B1 B2 B3 C1 C2 C3 1 1 1 1 111010 1 0 0 2 20 200 4 8 12 NA NA NA 1 2 1 1 111010 1 0 0 4 NA 400 5 9 NA NA NA NA 1 1 2 1 111010 1 0 0 6 60 NA NA 10 14 NA NA NA 1 2 2 1 111010 1 0 0 NA 80 800 7 11 15 NA NA NA 1 1 3 2 111010 0 1 0 1 2 1 2 2 2 10 20 30 1 2 3 2 111010 0 1 0 2 NA 1 2 2 NA 40 50 NA 1 1 4 2 111010 0 1 0 1 1 NA NA 2 2 70 80 90 1 2 4 2 111010 0 1 0 NA 2 1 2 2 10 100 110 120 1 1 1 3 010010 0 0 1 10 20 10 200 200 200 1 2 3 1 2 1 3 001000 0 0 1 20 NA 10 200 200 200 4 5 9 1 1 2 3 101000 0 0 1 10 10 NA 200 200 200 7 8 NA 1 2 2 3 011010 0 0 1 NA 20 10 200 200 200 10 11 12 ", sep = "", header = TRUE, stringsAsFactors = FALSE) df df2 <- df[df$region == 2, names(df) %in% c(paste("C", seq_along(1:3), sep=''''))] df2 # C1 C2 C3 # 5 10 20 30 # 6 40 50 NA # 7 70 80 90 # 8 100 110 120

Tengo un gran conjunto de datos y me gustaría leer columnas específicas o eliminar todas las demás.

data <- read.dta("file.dta")

Selecciono las columnas que no me interesan:

var.out <- names(data)[!names(data) %in% c("iden", "name", "x_serv", "m_serv")]

y que me gustaría hacer algo como:

for(i in 1:length(var.out)) { paste("data$", var.out[i], sep="") <- NULL }

para eliminar todas las columnas no deseadas. ¿Es esta la solución óptima?


Aquí hay una solución rápida para esto. Digamos que tienes un marco de datos X con tres columnas A, B y C:

> X<-data.frame(A=c(1,2),B=c(3,4),C=c(5,6)) > X A B C 1 1 3 5 2 2 4 6

Si quiero eliminar una columna, diga B, solo use grep en los nombres de columna para obtener el índice de la columna, que luego puede usar para omitir la columna.

> X<-X[,-grep("B",colnames(X))]

Su nuevo marco de datos X sería similar al siguiente (esta vez sin la columna B):

> X A C 1 1 5 2 2 6

La belleza de grep es que puede especificar varias columnas que coincidan con la expresión regular. Si tuviera X con cinco columnas (A, B, C, D, E):

> X<-data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,8),E=c(9,10)) > X A B C D E 1 1 3 5 7 9 2 2 4 6 8 10

Saque las columnas B y D:

> X<-X[,-grep("B|D",colnames(X))] > X A C E 1 1 5 9 2 2 6 10

EDITAR: Teniendo en cuenta la sugerencia grepl de Matthew Lundberg en los comentarios a continuación:

> X<-data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,8),E=c(9,10)) > X A B C D E 1 1 3 5 7 9 2 2 4 6 8 10 > X<-X[,!grepl("B|D",colnames(X))] > X A C E 1 1 5 9 2 2 6 10

Si intento eliminar una columna que no existe, no debería ocurrir nada:

> X<-X[,!grepl("G",colnames(X))] > X A C E 1 1 5 9 2 2 6 10


Cambié el código a:

# read data dat<-read.dta("file.dta") # vars to delete var.in<-c("iden", "name", "x_serv", "m_serv") # what I''m keeping var.out<-setdiff(names(dat),var.in) # keep only the ones I want dat <- dat[var.out]

De todos modos, la respuesta de juba es la mejor solución para mi problema!


Debe utilizar la indexación o la función de subset . Por ejemplo :

R> df <- data.frame(x=1:5, y=2:6, z=3:7, u=4:8) R> df x y z u 1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7 5 5 6 7 8

Luego puede usar la función which y el operador - en la indexación de columnas:

R> df[ , -which(names(df) %in% c("z","u"))] x y 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6

O, mucho más simple, use el argumento de select de la función de subset : luego puede usar el operador - directamente en un vector de nombres de columna, ¡e incluso puede omitir las comillas alrededor de los nombres!

R> subset(df, select=-c(z,u)) x y 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6

Tenga en cuenta que también puede seleccionar las columnas que desee en lugar de eliminar las demás:

R> df[ , c("x","y")] x y 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 R> subset(df, select=c(x,y)) x y 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6


Intenté eliminar una columna mientras utilizaba el paquete data.table y obtuve un resultado inesperado. Creo que vale la pena publicar lo siguiente. Sólo una pequeña nota de advertencia.

[Editado por Mateo ...]

DF = read.table(text = " fruit state grade y1980 y1990 y2000 apples Ohio aa 500 100 55 apples Ohio bb 0 0 44 apples Ohio cc 700 0 33 apples Ohio dd 300 50 66 ", sep = "", header = TRUE, stringsAsFactors = FALSE) DF[ , !names(DF) %in% c("grade")] # all columns other than ''grade'' fruit state y1980 y1990 y2000 1 apples Ohio 500 100 55 2 apples Ohio 0 0 44 3 apples Ohio 700 0 33 4 apples Ohio 300 50 66 library(''data.table'') DT = as.data.table(DF) DT[ , !names(dat4) %in% c("grade")] # not expected !! not the same as DF !! [1] TRUE TRUE FALSE TRUE TRUE TRUE DT[ , !names(DT) %in% c("grade"), with=FALSE] # that''s better fruit state y1980 y1990 y2000 1: apples Ohio 500 100 55 2: apples Ohio 0 0 44 3: apples Ohio 700 0 33 4: apples Ohio 300 50 66

Básicamente, la sintaxis de data.table NO es exactamente la misma que data.frame . De hecho, hay muchas diferencias, ver Preguntas frecuentes 1.1 y Preguntas frecuentes 2.17. ¡Usted ha sido advertido!


No puedo responder tu pregunta en los comentarios debido a la baja puntuación de reputación.

El siguiente código le dará un error porque la función de pegar devuelve una cadena de caracteres

for(i in 1:length(var.out)) { paste("data$", var.out[i], sep="") <- NULL }

Aquí hay una posible solución:

for(i in 1:length(var.out)) { text_to_source <- paste0 ("data$", var.out[i], "<- NULL") # Write a line of your # code like a character string eval (parse (text=text_to_source)) # Source a text that contains a code }

o simplemente hacer:

for(i in 1:length(var.out)) { data[var.out[i]] <- NULL }


No utilice -which() para esto, es extremadamente peligroso. Considerar:

dat <- data.frame(x=1:5, y=2:6, z=3:7, u=4:8) dat[ , -which(names(dat) %in% c("z","u"))] ## works as expected dat[ , -which(names(dat) %in% c("foo","bar"))] ## deletes all columns! Probably not what you wanted...

En su lugar, utilice el subconjunto o el ! función:

dat[ , !names(dat) %in% c("z","u")] ## works as expected dat[ , !names(dat) %in% c("foo","bar")] ## returns the un-altered data.frame. Probably what you want

He aprendido esto de la experiencia dolorosa. No use en exceso lo which() !


También puedes probar el paquete dplyr :

R> df <- data.frame(x=1:5, y=2:6, z=3:7, u=4:8) R> df x y z u 1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7 5 5 6 7 8 R> library(dplyr) R> dplyr::select(df2, -c(x, y)) # remove columns x and y z u 1 3 4 2 4 5 3 5 6 4 6 7 5 7 8


Primero , puede usar la indexación directa (con vectores booleanos) en lugar de volver a acceder a los nombres de columna si está trabajando con el mismo marco de datos; será más seguro según lo señalado por Ista, y más rápido de escribir y ejecutar. Entonces lo que solo necesitarás es:

var.out.bool <- !names(data) %in% c("iden", "name", "x_serv", "m_serv")

y luego, simplemente reasignar datos:

data <- data[,var.out.bool] # or... data <- data[,var.out.bool, drop = FALSE] # You will need this option to avoid the conversion to an atomic vector if there is only one column left

Segundo , más rápido de escribir, puede asignar directamente NULL a las columnas que desea eliminar:

data[c("iden", "name", "x_serv", "m_serv")] <- list(NULL) # You need list() to respect the target structure.

Finalmente , puede usar subconjunto (), pero en realidad no se puede usar en el código (incluso el archivo de ayuda advierte sobre él). Específicamente, un problema para mí es que si desea utilizar directamente la función de eliminación de susbset (), debe escribir sin comillas la expresión correspondiente a los nombres de columna:

subset( data, select = -c("iden", "name", "x_serv", "m_serv") ) # WILL NOT WORK subset( data, select = -c(iden, name, x_serv, m_serv) ) # WILL

Como beneficio adicional , aquí hay un pequeño punto de referencia de las diferentes opciones, que muestra claramente que el subconjunto es el más lento, y que el primer método de reasignación es el más rápido:

re_assign(dtest, drop_vec) 46.719 52.5655 54.6460 59.0400 1347.331 null_assign(dtest, drop_vec) 74.593 83.0585 86.2025 94.0035 1476.150 subset(dtest, select = !names(dtest) %in% drop_vec) 106.280 115.4810 120.3435 131.4665 65133.780 subset(dtest, select = names(dtest)[!names(dtest) %in% drop_vec]) 108.611 119.4830 124.0865 135.4270 1599.577 subset(dtest, select = -c(x, y)) 102.026 111.2680 115.7035 126.2320 1484.174

El código está abajo:

dtest <- data.frame(x=1:5, y=2:6, z = 3:7) drop_vec <- c("x", "y") null_assign <- function(df, names) { df[names] <- list(NULL) df } re_assign <- function(df, drop) { df <- df [, ! names(df) %in% drop, drop = FALSE] df } res <- microbenchmark( re_assign(dtest,drop_vec), null_assign(dtest,drop_vec), subset(dtest, select = ! names(dtest) %in% drop_vec), subset(dtest, select = names(dtest)[! names(dtest) %in% drop_vec]), subset(dtest, select = -c(x, y) ), times=5000) plt <- ggplot2::qplot(y=time, data=res[res$time < 1000000,], colour=expr) plt <- plt + ggplot2::scale_y_log10() + ggplot2::labs(colour = "expression") + ggplot2::scale_color_discrete(labels = c("re_assign", "null_assign", "subset_bool", "subset_names", "subset_drop")) + ggplot2::theme_bw(base_size=16) print(plt)


df2 <- df[!names(df) %in% c("c1", "c2")]