Eliminar una columna completa de un data.frame en R


267

¿Alguien sabe cómo eliminar una columna completa de un data.frame en R? Por ejemplo, si me dan este data.frame:

> head(data)
   chr       genome region
1 chr1 hg19_refGene    CDS
2 chr1 hg19_refGene   exon
3 chr1 hg19_refGene    CDS
4 chr1 hg19_refGene   exon
5 chr1 hg19_refGene    CDS
6 chr1 hg19_refGene   exon

y quiero eliminar la segunda columna.


Respuestas:


414

Puedes configurarlo en NULL.

> Data$genome <- NULL
> head(Data)
   chr region
1 chr1    CDS
2 chr1   exon
3 chr1    CDS
4 chr1   exon
5 chr1    CDS
6 chr1   exon

Como se señaló en los comentarios, aquí hay algunas otras posibilidades:

Data[2] <- NULL    # Wojciech Sobala
Data[[2]] <- NULL  # same as above
Data <- Data[,-2]  # Ian Fellows
Data <- Data[-2]   # same as above

Puede eliminar varias columnas a través de:

Data[1:2] <- list(NULL)  # Marek
Data[1:2] <- NULL        # does not work!

Sin embargo, tenga cuidado con el subconjunto de matrices, ya que puede terminar con un vector:

Data <- Data[,-(2:3)]             # vector
Data <- Data[,-(2:3),drop=FALSE]  # still a data.frame

48
o puede usar: Datos <- Datos [, - 2]
Ian Fellows

2
con la coma también puede controlar el argumento "soltar", que cuando FALSO significa que data.frame permanece como data.frame cuando el resultado consta de solo una columna; sin la coma siempre obtendrá un data.frame si hay varias columnas izquierda o solo una - se ignora la caída para la extracción [-2]
mdsumner

3
@mdsumner Data[-2]no necesita dropargumentos porque siempre regresa data.framede data.frame. Y creo que esta es una forma mucho mejor de columnas localizadas (y solo columnas) en data.frame(y es más rápido). Compruebe: cars[-1](una columna data.frame) o mejor cars[-(1:2)]: data frame with 0 columns and 50 rows.
Marek

1
También puede escribir Datos [2] <- NULL
Wojciech Sobala

11
Consejo menor: cuando Data[c(1,2)]<-list(NULL)se necesita eliminar varias columnas .
Marek

69

Para eliminar una o más columnas por nombre, cuando se conocen los nombres de las columnas (en lugar de determinarse en tiempo de ejecución), me gusta la subset()sintaxis. Por ejemplo, para el marco de datos

df <- data.frame(a=1:3, d=2:4, c=3:5, b=4:6)

para eliminar solo la acolumna que podrías hacer

Data <- subset( Data, select = -a )

y para eliminar las columnas by dque podrías hacer

Data <- subset( Data, select = -c(d, b ) )

Puede eliminar todas las columnas entre dy bcon:

Data <- subset( Data, select = -c( d : b )

Como dije anteriormente, esta sintaxis solo funciona cuando se conocen los nombres de las columnas. No funcionará cuando digamos que los nombres de columna se determinan mediante programación (es decir, asignados a una variable). Reproduciré esta Advertencia de la ?subsetdocumentación:

Advertencia:

Esta es una función de conveniencia diseñada para su uso interactivo. Para la programación es mejor usar las funciones de subconjunto estándar como '[', y en particular la evaluación no estándar del argumento 'subconjunto' puede tener consecuencias imprevistas.


26

(Para completar) Si desea eliminar columnas por nombre, puede hacer esto:

cols.dont.want <- "genome"
cols.dont.want <- c("genome", "region") # if you want to remove multiple columns

data <- data[, ! names(data) %in% cols.dont.want, drop = F]

La inclusión drop = Fasegura que el resultado seguirá siendo un data.frameincluso si solo queda una columna.


22

Las respuestas publicadas son muy buenas cuando se trabaja con data.frames. Sin embargo, estas tareas pueden ser bastante ineficientes desde una perspectiva de memoria. Con datos grandes, eliminar una columna puede llevar una cantidad de tiempo inusualmente larga y / o fallar debido a out of memoryerrores. El paquete data.tableayuda a resolver este problema con el :=operador:

library(data.table)
> dt <- data.table(a = 1, b = 1, c = 1)
> dt[,a:=NULL]
     b c
[1,] 1 1

Debería armar un ejemplo más grande para mostrar las diferencias. Actualizaré esta respuesta en algún momento con eso.


3
La data.table::setfunción se puede usar en data.frames para eliminar o modificar una columna al instante, sin hacer copias. Ver aquí
GSee

8

Hay varias opciones para eliminar una o más columnas con dplyr::select()y algunas funciones auxiliares. Las funciones auxiliares pueden ser útiles porque algunas no requieren nombrar todas las columnas específicas para descartar. Tenga en cuenta que para soltar columnas usando select()debe usar una guía -para negar los nombres de columna.

Usando los dplyr::starwarsdatos de muestra para alguna variedad en los nombres de columna:

library(dplyr)

starwars %>% 
  select(-height) %>%                  # a specific column name
  select(-one_of('mass', 'films')) %>% # any columns named in one_of()
  select(-(name:hair_color)) %>%       # the range of columns from 'name' to 'hair_color'
  select(-contains('color')) %>%       # any column name that contains 'color'
  select(-starts_with('bi')) %>%       # any column name that starts with 'bi'
  select(-ends_with('er')) %>%         # any column name that ends with 'er'
  select(-matches('^v.+s$')) %>%       # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%          # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 

También puede colocar por número de columna:

starwars %>% 
  select(-2, -(4:10)) # column 2 and columns 4 through 10

Gran respuesta. ¿Alguna idea sobre cómo soltar una columna que contiene un cierto valor en cualquiera de sus filas (no en el nombre de la columna como propuso anteriormente)?
Laura K

df [, - which (sapply (df, function (x) any (x == a)))], donde df es su marco de datos y a es su valor específico, por ejemplo: mtcars [, - which (sapply (mtcars, function (x) any (x == 4)))]
Nanami

7

Con esto puedes eliminar columny almacenar variableen otro variable.

df = subset(data, select = -c(genome) )
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.