visualizar mtcars functions español ejemplos data crear column r dataframe

mtcars - ¿Qué puede hacer R sobre un formato de datos desordenado?



r data frame mtcars (6)

A veces veo datos publicados en una pregunta de desbordamiento de pila con formato como en esta pregunta . Esta no es la primera vez, por lo que he decidido hacer una pregunta al respecto y responder a la pregunta de manera que los datos publicados sean aceptables.

Pondré aquí el ejemplo del conjunto de datos solo en caso de que se elimine la pregunta.

+------------+------+------+----------+--------------------------+ | Date | Emp1 | Case | Priority | PriorityCountinLast7days | +------------+------+------+----------+--------------------------+ | 2018-06-01 | A | A1 | 0 | 0 | | 2018-06-03 | A | A2 | 0 | 1 | | 2018-06-03 | A | A3 | 0 | 2 | | 2018-06-03 | A | A4 | 1 | 1 | | 2018-06-03 | A | A5 | 2 | 1 | | 2018-06-04 | A | A6 | 0 | 3 | | 2018-06-01 | B | B1 | 0 | 1 | | 2018-06-02 | B | B2 | 0 | 2 | | 2018-06-03 | B | B3 | 0 | 3 | +------------+------+------+----------+--------------------------+

Como puede ver, esta no es la forma correcta de publicar datos. Como escribió un usuario en un comentario,

Debe haber tomado un poco de tiempo formatear los datos de la forma en que los muestra aquí. Desafortunadamente, este no es un buen formato para copiar y pegar.

Creo que esto lo dice todo. El autor de la pregunta tiene buenas intenciones y le llevó algo de trabajo y tiempo tratar de ser amable, pero el resultado no es bueno.

¿Qué puede hacer el código R para hacer que esa tabla sea utilizable, en todo caso? ¿Tomará muchos problemas?


Bueno, sobre este conjunto de datos específico, utilicé la función de importación en RStudio, pero di un paso adicional de antemano.

  1. Copie el conjunto de datos en el archivo de Bloc de notas.
  2. Reemplazar todos | personajes con ,
  3. Import el archivo de Bloc de notas usando read.csv a RStudio usando este código (columnas separadas por , ).

Pero, si te refieres a usar la R para entenderlo en un solo paso, entonces no tengo idea.


El problema no es tanto la cantidad de líneas de código que toma, dos o cinco, no hay mucha diferencia. La pregunta es más si funcionará más allá del ejemplo que publicaste aquí.

No he encontrado este tipo de cosas en la naturaleza, pero tuve la oportunidad de construir un par de ejemplos más que pensé que posiblemente podría existir.

dput(mtcars %>% head(10), file = ''reproducible.txt'')

Mi ir a una función

df <- structure(list(mpg = c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2), cyl = c(6, 6, 4, 6, 8, 6, 8, 4, 4, 6), disp = c(160, 160, 108, 258, 360, 225, 360, 146.7, 140.8, 167.6), hp = c(110, 110, 93, 110, 175, 105, 245, 62, 95, 123), drat = c(3.9, 3.9, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92), wt = c(2.62, 2.875, 2.32, 3.215, 3.44, 3.46, 3.57, 3.19, 3.15, 3.44), qsec = c(16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20, 22.9, 18.3), vs = c(0, 0, 1, 1, 0, 1, 0, 1, 1, 1), am = c(1, 1, 1, 0, 0, 0, 0, 0, 0, 0), gear = c(4, 4, 4, 3, 3, 3, 3, 4, 4, 4), carb = c(4, 4, 1, 1, 2, 1, 4, 2, 2, 4)), .Names = c("mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", "gear", "carb"), row.names = c("Mazda RX4", "Mazda RX4 Wag", "Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", "Valiant", "Duster 360", "Merc 240D", "Merc 230", "Merc 280"), class = "data.frame")


La respuesta corta a la pregunta es sí, el código R puede resolver ese desorden y no, no requiere tantos problemas.

El primer paso después de copiar y pegar la tabla en una sesión R es leerla con read.table configurando los argumentos de header , sep , comment.char y strip.white .

Los créditos por recordarme los argumentos comment.char y strip.white van a @nicola, y su comentario.

dat <- read.table(text = " +------------+------+------+----------+--------------------------+ | Date | Emp1 | Case | Priority | PriorityCountinLast7days | +------------+------+------+----------+--------------------------+ | 2018-06-01 | A | A1 | 0 | 0 | | 2018-06-03 | A | A2 | 0 | 1 | | 2018-06-03 | A | A3 | 0 | 2 | | 2018-06-03 | A | A4 | 1 | 1 | | 2018-06-03 | A | A5 | 2 | 1 | | 2018-06-04 | A | A6 | 0 | 3 | | 2018-06-01 | B | B1 | 0 | 1 | | 2018-06-02 | B | B2 | 0 | 2 | | 2018-06-03 | B | B3 | 0 | 3 | +------------+------+------+----------+--------------------------+ ", header = TRUE, sep = "|", comment.char = "+", strip.white = TRUE)

Pero como puedes ver hay algunos problemas con el resultado.

dat X Date Emp1 Case Priority PriorityCountinLast7days X.1 1 NA 2018-06-01 A A1 0 0 NA 2 NA 2018-06-03 A A2 0 1 NA 3 NA 2018-06-03 A A3 0 2 NA 4 NA 2018-06-03 A A4 1 1 NA 5 NA 2018-06-03 A A5 2 1 NA 6 NA 2018-06-04 A A6 0 3 NA 7 NA 2018-06-01 B B1 0 1 NA 8 NA 2018-06-02 B B2 0 2 NA 9 NA 2018-06-03 B B3 0 3 NA

Para que los separadores comiencen y terminen cada fila de datos, haga que R crea que esos separadores marcan columnas adicionales, que no es lo que se entiende por el OP de la pregunta original.

Así que el segundo paso es mantener solo las columnas reales . Haré este subconjunto de las columnas por sus números, fáciles de hacer, por lo general son la primera y la última columna.

dat <- dat[-c(1, ncol(dat))] dat Date Emp1 Case Priority PriorityCountinLast7days 1 2018-06-01 A A1 0 0 2 2018-06-03 A A2 0 1 3 2018-06-03 A A3 0 2 4 2018-06-03 A A4 1 1 5 2018-06-03 A A5 2 1 6 2018-06-04 A A6 0 3 7 2018-06-01 B B1 0 1 8 2018-06-02 B B2 0 2 9 2018-06-03 B B3 0 3

Eso no fue demasiado difícil, mucho mejor.
En este caso, todavía hay un problema, para obligar a la columna Date a clase Date .

dat$Date <- as.Date(dat$Date)

Y el resultado es satisfactorio.

str(dat) ''data.frame'': 9 obs. of 5 variables: $ Date : Date, format: "2018-06-01" "2018-06-03" ... $ Emp1 : Factor w/ 2 levels "A","B": 1 1 1 1 1 1 2 2 2 $ Case : Factor w/ 9 levels "A1","A2","A3",..: 1 2 3 4 5 6 7 8 9 $ Priority : int 0 0 0 1 2 0 0 0 0 $ PriorityCountinLast7days: int 0 1 2 1 1 3 1 2 3

Tenga en cuenta que no he establecido las stringsAsFactors = FALSE argumentos más o menos estándarAsFactors stringsAsFactors = FALSE . Si es necesario, esto debe hacerse cuando se ejecuta read.table .

Todo el proceso tomó solo 3 líneas de código base R

Finalmente, el resultado final en formato dput , como debería ser en primer lugar.

dat <- structure(list(Date = structure(c(17683, 17685, 17685, 17685, 17685, 17686, 17683, 17684, 17685), class = "Date"), Emp1 = c("A", "A", "A", "A", "A", "A", "B", "B", "B"), Case = c("A1", "A2", "A3", "A4", "A5", "A6", "B1", "B2", "B3"), Priority = c(0, 0, 0, 1, 2, 0, 0, 0, 0), PriorityCountinLast7days = c(0, 1, 2, 1, 1, 3, 1, 2, 3)), row.names = c(NA, -9L), class = "data.frame")


Tal como se sugirió, podría usar la función Dput para guardar el contenido de un marco de datos en un archivo, abrir el archivo en un editor de texto y pegar su contenido. Un ejemplo de conjunto de datos de mtcar limitado a las primeras 10 filas:

dput(mtcars %>% head(10), file = ''reproducible.txt'')

El contenido de reproducible.txt se puede usar para hacer un marco de datos / tibble como se muestra a continuación. En tal caso, el formato es legible por máquina, pero a primera vista el ser humano no lo puede comprender (sin pegarlo en R).

df <- structure(list(mpg = c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2), cyl = c(6, 6, 4, 6, 8, 6, 8, 4, 4, 6), disp = c(160, 160, 108, 258, 360, 225, 360, 146.7, 140.8, 167.6), hp = c(110, 110, 93, 110, 175, 105, 245, 62, 95, 123), drat = c(3.9, 3.9, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92), wt = c(2.62, 2.875, 2.32, 3.215, 3.44, 3.46, 3.57, 3.19, 3.15, 3.44), qsec = c(16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20, 22.9, 18.3), vs = c(0, 0, 1, 1, 0, 1, 0, 1, 1, 1), am = c(1, 1, 1, 0, 0, 0, 0, 0, 0, 0), gear = c(4, 4, 4, 3, 3, 3, 3, 4, 4, 4), carb = c(4, 4, 1, 1, 2, 1, 4, 2, 2, 4)), .Names = c("mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", "gear", "carb"), row.names = c("Mazda RX4", "Mazda RX4 Wag", "Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", "Valiant", "Duster 360", "Merc 240D", "Merc 230", "Merc 280"), class = "data.frame")


Utilizando data.table::fread :

x = '' +------------+------+------+----------+--------------------------+ | Date | Emp1 | Case | Priority | PriorityCountinLast7days | +------------+------+------+----------+--------------------------+ | 2018-06-01 | A | A1 | 0 | 0 | | 2018-06-03 | A | A2 | 0 | 1 | | 2018-06-03 | A | A3 | 0 | 2 | | 2018-06-03 | A | A4 | 1 | 1 | | 2018-06-03 | A | A5 | 2 | 1 | | 2018-06-04 | A | A6 | 0 | 3 | | 2018-06-01 | B | B1 | 0 | 1 | | 2018-06-02 | B | B2 | 0 | 2 | | 2018-06-03 | B | B3 | 0 | 3 | +------------+------+------+----------+--------------------------+ '' fread(gsub(''//+.+//n'' ,'''', x, perl = T), drop=c(1,7)) # Date Emp1 Case Priority PriorityCountinLast7days # 1: 2018-06-01 A A1 0 0 # 2: 2018-06-03 A A2 0 1 # 3: 2018-06-03 A A3 0 2 # 4: 2018-06-03 A A4 1 1 # 5: 2018-06-03 A A5 2 1 # 6: 2018-06-04 A A6 0 3 # 7: 2018-06-01 B B1 0 1 # 8: 2018-06-02 B B2 0 2 # 9: 2018-06-03 B B3 0 3

La parte gsub elimina las reglas horizontales. drop elimina las columnas adicionales causadas por delimitadores en los extremos de la línea.


md_table <- scan(text = " +------------+------+------+----------+--------------------------+ | Date | Emp1 | Case | Priority | PriorityCountinLast7days | +------------+------+------+----------+--------------------------+ | 2018-06-01 | A | A1 | 0 | 0 | | 2018-06-03 | A | A2 | 0 | 1 | | 2018-06-03 | A | A3 | 0 | 2 | | 2018-06-03 | A | A4 | 1 | 1 | | 2018-06-03 | A | A5 | 2 | 1 | | 2018-06-04 | A | A6 | 0 | 3 | | 2018-06-01 | B | B1 | 0 | 1 | | 2018-06-02 | B | B2 | 0 | 2 | | 2018-06-03 | B | B3 | 0 | 3 | +------------+------+------+----------+--------------------------+", what = "", sep = "", comment.char = "+", quiet = TRUE) ## it is clear that there are 5 columns mat <- matrix(md_table[md_table != "|"], ncol = 5, byrow = TRUE) # [,1] [,2] [,3] [,4] [,5] # [1,] "Date" "Emp1" "Case" "Priority" "PriorityCountinLast7days" # [2,] "2018-06-01" "A" "A1" "0" "0" # [3,] "2018-06-03" "A" "A2" "0" "1" # [4,] "2018-06-03" "A" "A3" "0" "2" # [5,] "2018-06-03" "A" "A4" "1" "1" # [6,] "2018-06-03" "A" "A5" "2" "1" # [7,] "2018-06-04" "A" "A6" "0" "3" # [8,] "2018-06-01" "B" "B1" "0" "1" # [9,] "2018-06-02" "B" "B2" "0" "2" #[10,] "2018-06-03" "B" "B3" "0" "3"

## a data frame with all character columns dat <- setNames(data.frame(mat[-1, ], stringsAsFactors = FALSE), mat[1, ]) # Date Emp1 Case Priority PriorityCountinLast7days #1 2018-06-01 A A1 0 0 #2 2018-06-03 A A2 0 1 #3 2018-06-03 A A3 0 2 #4 2018-06-03 A A4 1 1 #5 2018-06-03 A A5 2 1 #6 2018-06-04 A A6 0 3 #7 2018-06-01 B B1 0 1 #8 2018-06-02 B B2 0 2 #9 2018-06-03 B B3 0 3

## or maybe just use `type.convert` on some columns? dat[] <- lapply(dat, type.convert)