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
subsetfunción. Por ejemplo :Luego puede usar la
whichfunción y el-operador en la indexación de columna:O, mucho más simple, use el
selectargumento de lasubsetfunció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
selectargumento de lasubsetfunción hizo el trabajo perfectamente! Gracias juba!whichno es necesario, ver la respuesta de Ista. ¡Pero el subconjunto con-es bueno! ¡No lo sabía!subsetse ve bien, pero la forma en que elimina silenciosamente los valores perdidos me parece bastante peligroso.subsetde 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
setdifftambién es útil:setdiff(names(dat), c("foo", "bar"))setdiffpropuesta 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
dplyrpaquete: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 <- irispor ejemplo. Este es el problema con el uso de índices negativos con valores calculados. Considere en sugrepllugar.Intenté eliminar una columna mientras usaba el paquete
data.tabley 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.tableNO 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.frameydata.tableclasesCambié el código a:
De todos modos, ¡la respuesta de juba es la mejor solución para mi problema!
fuente
selectargumento de lasubsetfunció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