Convertir vector de caracteres con nombre en data.frame

86

Tengo un vector de caracteres con nombre devuelto por xmlAttrs como este:

testVect <- structure(c("11.2.0.3.0", "12.89", "12.71"), .Names = c("db_version", 
             "elapsed_time", "cpu_time"))

Me gustaría convertirlo en un marco de datos que se vea así:

testDF <- data.frame("db_version"="11.2.0.3.0","elapsed_time"=12.89,"cpu_time"=12.71)
head(testDF)
  db_version elapsed_time cpu_time
1 11.2.0.3.0        12.89    12.71
Tyler Muth
fuente

Respuestas:

84

Es tan simple como data.frame(as.list(testVect)). O si desea tipos de datos sensibles para sus columnas, data.frame(lapply(testVect, type.convert), stringsAsFactors=FALSE).

Matthew Plourde
fuente
1
Curiosamente, el análogo tibble de esto no funciona: data_frame(as.list(testVect))devuelve un marco de datos de 5 filas.
CoderGuy123
5
@Deleet tibble funcionará con as_tibble(as.list(testVect))o as_data_frame(as.list(testVect))( as_data_framees un alias de as_tibble).
JWilliman
2
De acuerdo con los comentarios de @Deleet y @JWillliman, data.table(as.list(...))no funciona, pero as.data.table(as.list(...))sí.
merv
@Matthew Plourde Ya sea stringsAsFactors True o False, da el mismo tipo de datos. ¿Cómo no cambiar el tipo de datos?
AMS
56

Las respuestas de @MatthewPlourde y @JackRyan funcionan, pero si tiene un vector con nombre largo, es molesto tener un marco de datos con una fila y muchas columnas. Si prefiere tener una columna de "clave" y una columna de "valor" con muchas filas, cualquiera de las siguientes debería funcionar:

data.frame(keyName=names(testVect), value=testVect, row.names=NULL)

##        keyName      value
## 1   db_version 11.2.0.3.0
## 2 elapsed_time      12.89
## 3     cpu_time      12.71


## Suggested by @JWilliman
tibble::enframe(testVect)

## # A tibble: 3 x 2
##   name         value
##   <chr>        <chr>
## 1 db_version   11.2.0.3.0
## 2 elapsed_time 12.89
## 3 cpu_time     12.71


## Suggested by @Joe
stack(testVect)
##       values          ind
## 1 11.2.0.3.0   db_version
## 2      12.89 elapsed_time
## 3      12.71     cpu_time
dnlbrky
fuente
triste que no haya una sola línea
JelenaČuklina
5
También se puede utilizar tibble::enframe(testVect).
JWilliman
2
stack(testVect)también hace esto pero deja los valores como caracteres.
Joe
@ Jelena-bioinf como una sola línea con sintaxis dplyr, puede usar testVect %>% as.list %>% as.data.frame %>% tidyr::gather()Esto en realidad produce las columnas 'clave' y 'valor' a las que se refirió @dnlbrky.
Agile Bean
stack()¡Qué función tan subestimada!
stevec
18

Voy a intentarlo con esto:

test.vector <- as.data.frame(t(testVect))
class(test.vector)
Jack Ryan
fuente
O incluso más corto, simplementedata.frame(t(testVect))
Tjebo
3

Solía usar las funciones sugeridas en estas respuestas ( as.list, as_tibble, t, enframe, etc.), pero desde entonces han descubierto que dplyr::bind_rowsahora trabaja para hacer exactamente lo que la pregunta original pregunta con una sola llamada de función.

library(dplyr)
testVect <- structure(c("11.2.0.3.0", "12.89", "12.71"), .Names = c("db_version", "elapsed_time", "cpu_time"))
testVect %>% bind_rows
#> # A tibble: 1 x 3
#>   db_version elapsed_time cpu_time
#>   <chr>      <chr>        <chr>   
#> 1 11.2.0.3.0 12.89        12.71

Creado el 10/11/2019 con el paquete reprex (v0.3.0)

Como se muestra en tidyverse: forma preferida de convertir un vector con nombre en un data.frame / tibble

Arthur Yip
fuente
0
named vector %>% as_tibble(.,rownames="column name of row.names")
BatmanFan
fuente
Por favor, agregue alguna explicación por aquí para que todos puedan aprender. A partir de ahora, una sola línea es un poco superficial.
armónica141