将命名列表有效地转换为data.frame

sin*_*dur 4 r list dataframe

我正在寻找一种有效的方式进行以下转换:

输入示例:

ob <- list(a = 2, b = 3)
Run Code Online (Sandbox Code Playgroud)

预期产量:

  key value
1   a     2
2   b     3
Run Code Online (Sandbox Code Playgroud)

当前(详细)解决方案:

data.frame(key = names(ob), value = unlist(ob, use.names = FALSE))
Run Code Online (Sandbox Code Playgroud)

mar*_*kus 6

尝试 stack

stack(ob)
#  values ind
#1      2   a
#2      3   b
Run Code Online (Sandbox Code Playgroud)

您需要更改名称.使用setNames

setNames(stack(ob), nm = c("value", "key"))
Run Code Online (Sandbox Code Playgroud)

基准

解决@Roland的评论, stack 似乎确实更有效率.stack出于效率原因,请不要使用OP的解决方案.

n <- 1e5
lst <- as.list(seq_len(n))
names(lst) <- paste0("a", seq_len(n))

library(microbenchmark)
benchmark <- microbenchmark(
  snoram = snoram(lst),
  markus = markus(lst), times = 50
)
benchmark
#Unit: milliseconds
#   expr      min       lq     mean   median       uq      max neval
# snoram   2.475258   2.594479   2.739639   2.652843   2.715575   5.92216    50
# markus 114.387692 119.028200 134.745626 137.524606 144.045112 162.11510    50
Run Code Online (Sandbox Code Playgroud)

使用的功能(到目前为止)

snoram <- function(l) {
  data.frame(key = names(l), value = unlist(l, use.names = FALSE),
             stringsAsFactors = FALSE) # this gives a hugh performance gain
                                       # thanks to @Roland
}

markus <- function(l) {
  setNames(stack(l), nm = c("value", "key"))
}
Run Code Online (Sandbox Code Playgroud)