Estoy trabajando con una API que parece devolver datos mal formados. La API debe devolver marcos de datos anidados, pero también devuelve listas vacías en ocasiones:
column_name
<list>
<data.frame [1 × 5]>
<data.frame [0 × 0]>
<data.frame [0 × 0]>
<list [0]>
...
Después de este paso, quiero usar unnest
para usar los datos en los marcos de datos anidados aguas abajo. Sin embargo, las listas vacías evitan que esto suceda. Lo que pensé hacer es:
- (1) Pruebe para ver si la entrada de la fila es una lista vacía
- (2) En caso afirmativo, convertir a un marco de datos vacío; si no, déjalo como está
Sin embargo, mis enfoques de prueba para las listas vacías han caído un poco, ya que un marco de datos es una lista. Actualmente estoy pensando en usar identical
o all.equal
junto con dim
para la prueba. Es decir, si las dimensiones de la entrada son [1,1], reemplace esta entrada con un marco de datos vacío.
(Me pregunto qué sucede en el caso en que tengo un marco de datos con dimensiones [1,1] pero en realidad también contiene datos ...)
¿Es esta la forma más R de hacer esto? He visto este comportamiento desde la API en otro lugar, por lo que necesitaré usar esta funcionalidad en varios lugares.
Nota: estoy usando el tidyverse, si eso impacta las respuestas.
3 respuestas
A menudo es más fácil limpiar los datos tan pronto como los obtiene de la API. Entonces, todo lo que sigue puede basarse en suposiciones seguras.
Para este ejemplo, cree una función que devuelva un tbl
con formato consistente utilizando la respuesta de la API. Cada tbl
tendrá las mismas columnas, pero algunas de ellas podrían llenarse con NA
si no estuvieran en la respuesta.
library(tidyr)
library(dplyr)
response_to_df <- function(id = NA_real_,
country = NA_character_,
wealth = NA_real_,
... # Catch extra columns you don't want
) {
tibble(id = id, country = country, wealth = wealth)
}
prepare_response_df <- function(response) {
do.call(response_to_df, response)
}
responses <- list(
tibble(id = 1:2, country = c("US", "DE"), wealth = c(95, 84)),
list(),
tibble(id = 3)
)
tibble(res = responses) %>%
mutate(nicer = lapply(res, prepare_response_df)) %>%
unnest(nicer)
# # A tibble: 4 x 3
# id country wealth
# <dbl> <chr> <dbl>
# 1 1 US 95
# 2 2 DE 84
# 3 NA NA NA
# 4 3 NA NA
Un marco de datos es un list
especial pero la clase es dataframe
. Puedes probar la clase de esta manera:
class(data.frame()) == "list"
> FALSE
class(list()) == "list"
> TRUE
Aquí hay una opción usando map
y if
library(dplyr)
library(purrr)
ir %>% mutate(data1=map(data, ~if(is.null(dim(.x))) data.frame() else .x)) %>%
unnest(data1)
Datos: siempre es útil proporcionar datos reproducibles de copiar y pegar
ir <- iris %>% group_by(Species) %>% nest()
ir$data[[2]]<-list()
Preguntas relacionadas
Nuevas preguntas
r
R es un entorno de software y lenguaje de programación de código abierto y gratuito para computación estadística, bioinformática, visualización y computación en general. Proporcione ejemplos mínimos y reproducibles junto con el resultado deseado. Use dput () para los datos y especifique todos los paquetes no base con llamadas a library (). No incruste imágenes para datos o código, use bloques de código con sangría en su lugar. Para preguntas relacionadas con estadísticas, use https://stats.stackexchange.com.