Tengo un gran conjunto de datos y me gustaría leer columnas específicas o descartar 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 de lo que me gustaría hacer algo como:
for(i in 1:length(var.out)) {
paste("data$", var.out[i], sep="") <- NULL
}
para soltar todas las columnas no deseadas. ¿Es esta la solución óptima?
subset(data, select=c(...))
ayuda en mi caso por dejar caer vars. Sin embargo, la pregunta era principalmente sobre lapaste("data$",var.out[i],sep="")
parte para acceder a las columnas de interés dentro del ciclo. ¿Cómo puedo pegar o de alguna manera componer el nombre de una columna? Gracias a todos por su atención y su ayudaRespuestas:
Debe usar la indexación o la
subset
función. Por ejemplo :Luego puede usar la
which
función y el-
operador en la indexación de columna:O, mucho más simple, use el
select
argumento de lasubset
función: luego puede usar el-
operador directamente en un vector de nombres de columna, ¡e incluso puede omitir las comillas alrededor de los nombres!Tenga en cuenta que también puede seleccionar las columnas que desee en lugar de soltar las otras:
fuente
select
argumento de lasubset
función hizo el trabajo perfectamente! Gracias juba!which
no es necesario, ver la respuesta de Ista. ¡Pero el subconjunto con-
es bueno! ¡No lo sabía!subset
se ve bien, pero la forma en que elimina silenciosamente los valores perdidos me parece bastante peligroso.subset
de hecho es muy conveniente, pero recuerde evitar usarlo a menos que esté usando R interactivamente. Consulte la Advertencia en la documentación de la función y esta pregunta SO para obtener más información.No lo use
-which()
para esto, es extremadamente peligroso. Considerar:En su lugar, use el subconjunto o la
!
función:He aprendido esto por experiencia dolorosa. ¡No lo uses en exceso
which()
!fuente
setdiff
también es útil:setdiff(names(dat), c("foo", "bar"))
setdiff
propuesta de @hadley es muy buena para largas listas de nombres.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 indicado por Ista, y más rápido escribir y ejecutar. Entonces, lo que solo necesitará es:
y luego, simplemente reasignar datos:
En segundo lugar , más rápido de escribir, puede asignar directamente NULL a las columnas que desea eliminar:
Finalmente , puede usar el subconjunto (), pero en realidad no se puede usar en el código (incluso el archivo de ayuda lo advierte). Específicamente, un problema para mí es que si desea utilizar directamente la función de caída de susbset (), debe escribir sin comillas la expresión correspondiente a los nombres de columna:
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:
El código está abajo:
fuente
NULL
, pero ¿por qué cuando pones más de dos nombres es necesario asignarlalist(NULL)
? Solo tengo curiosidad por saber cómo funciona, porque lo intenté con un solo nombre y no necesitolist()
$
o[[
), el uso en<- list(NULL)
realidad conducirá a resultados incorrectos. Si accede a un subconjunto del marco de datos con una o varias columnas,<- list(NULL)
es el camino a seguir, incluso si no es necesario para un marco de datos de una columna (porquedf['myColumns']
se convertirá en un vector si es necesario).También puedes probar el
dplyr
paquete:fuente
dplyr::select(df2, -one_of(c('x','y')))
seguirá funcionando (con una advertencia) incluso si algunas de las columnas con nombre no existenAquí hay una solución rápida para esto. Digamos que tiene un marco de datos X con tres columnas A, B y C:
Si quiero eliminar una columna, digamos B, solo use grep en colnames para obtener el índice de columna, que luego puede usar para omitir la columna.
Su nuevo marco de datos X se vería así (esta vez sin la columna B):
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):
Saque las columnas B y D:
EDITAR: Teniendo en cuenta la sugerencia grepl de Matthew Lundberg en los comentarios a continuación:
Si trato de soltar una columna que no existe, no debería pasar nada:
fuente
X[,-grep("B",colnames(X))]
no devolverá ninguna columna en el caso de que no contenga ningún nombre de columnaB
, en lugar de devolver todas las columnas como se desearía. Considere conX <- iris
por ejemplo. Este es el problema con el uso de índices negativos con valores calculados. Considere en sugrepl
lugar.Intenté eliminar una columna mientras usaba el paquete
data.table
y obtuve un resultado inesperado. Creo que vale la pena publicar lo siguiente. Solo una pequeña nota de advertencia.[Editado por Matthew ...]
Básicamente, la sintaxis para
data.table
NO es exactamente la misma quedata.frame
. De hecho, hay muchas diferencias, consulte las preguntas frecuentes 1.1 y 2.17. ¡Usted ha sido advertido!fuente
DT[,var.out := NULL]
para eliminar las columnas que desea hacerlo.data.frame
ydata.table
clasesCambié el código a:
De todos modos, ¡la respuesta de juba es la mejor solución para mi problema!
fuente
select
argumento de lasubset
función en mi código. Solo quería ver cómo podía acceder a columnas arbitrarias en un bucle en caso de que quisiera hacer algo más que simplemente soltar la columna. el conjunto de datos original tiene aproximadamente 1200 vars y solo estoy interesado en usar 4 de ellos sin saber exactamente dónde están.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 gran conjunto de datos. Las columnas se seleccionan como en una de las respuestas de juba, excepto que uso una función de pegar para seleccionar un conjunto de columnas con nombres numerados secuencialmente:
fuente
fuente
No puedo responder a su 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 pegar devuelve una cadena de caracteres
Aquí hay una posible solución:
o simplemente hacer:
fuente
dfnum = df[,-c(8,9)]
fuente