将不完整的列表解析为具有两个不同问题的数据框
如果通过R请求Web数据,则通常使用json或xml,其中如果字段没有值,则字段未命名。有时,甚至没有任何数据,它作为某个索引的空列表出现。所以,我认为这是两个不同的问题。我提出了我用来解决这个问题的解决方案,但我知道那里有一些更好的解决方案。对于初学者来说,我创建了一个非常混乱和虚假的列表,它缺少字段名称(有意从xml,json规范中)并且缺少整个索引(也是有意的)。将不完整的列表解析为具有两个不同问题的数据框
(messy_list <- list(list(x = 2, y = 3),
list(),
list(y = 4),
list(x = 5)))
现在,这里是我如何分解它,以我会说是“解决”。
library(plyr)
messy_list_no_empties <- lapply(messy_list, function(x) if(length(x) == 0) {list(NA, NA)} else x)
ldply(messy_list_no_empties, data.frame)[,1:2]
最终的结果是我在找的,但我想找到一个更优雅的方式来处理这个问题。
随着purrr::map_df
,
library(purrr)
messy_list <- list(list(x = 2, y = 3),
list(),
list(y = 4),
list(x = 5))
messy_list %>% map_df(~list(x = .x$x %||% NA,
y = .x$y %||% NA))
#> # A tibble: 4 × 2
#> x y
#> <dbl> <dbl>
#> 1 2 3
#> 2 NA NA
#> 3 NA 4
#> 4 5 NA
map_df
遍历列表像lapply
并且强制的结果,一个data.frame。这个函数(在purrr的公式中)用x
和y
元素组装一个列表,如果他们在那里寻找现有的值。如果不是,则子集将返回NULL
,其中%||%
将替换后面的值,即NA
。
在大多相当于基R,
as.data.frame(do.call(rbind,
lapply(messy_list, function(.x){
list(x = ifelse(is.null(.x$x), NA, .x$x),
y = ifelse(is.null(.x$y), NA, .x$y))
})))
#> x y
#> 1 2 3
#> 2 NA NA
#> 3 NA 4
#> 4 5 NA
注基座的办法将不会处理不同类型的井。要做到这一点,强制所有的字符(rbind
可能会反正,所以只需添加stringsAsFactors = FALSE
到as.data.frame
)和lapply
type.convert
。
这看起来正是我在找什么。我会等几个小时,并接受你的答案,如果更好的一个没有出现。 – cylondude
无需等待。用复选标记标记它,然后你仍然可以改变它。 –
你的方法已经相当紧凑,但如果你正在寻找其他方法,一种方法是在使用rbindlist
从data.table
:
library(data.table)
new_list <- lapply(messy_list, function(x) if(identical(x,list())){list(x = NA)} else {x})
rbindlist(new_list, fill = T, use.names = T)
# x y
#1: 2 3
#2: NA NA
#3: NA 4
#4: 5 NA
注意我们所需要的lapply
所以它不会掉落行是空的
你真的想保留完全是“NA”的行吗? –
是的。我需要他们在同一个索引。 – cylondude