首页 > 解决方案 > 来自向量列表的数据框

问题描述

我有 4 个不同长度的向量 (d1,d2,d3,d4),我从中创建这样的数据框

df <- data.frame(
  x = c(
    seq_along(d1),
    seq_along(d2),
    seq_along(d3),
    seq_along(d4)
  ),
  y = c(
    d1,
    d2,
    d3,
    d4
  ),
  id = c(
    rep("d1", times = length(d1)), 
    rep("d2", times = length(d2)),
    rep("d3", times = length(d3)),
    rep("d4", times = length(d4))
  ))

添加一个新向量意味着在 3 个不同的地方添加它,这是我想要避免的。理想情况下,我想d1,d2,d3,d4传入一个函数,然后返回数据框。

第一步似乎是将向量包装到一个列表中并命名它们。

l <- list(d1,d2,d3,d4)
names(l) <- c("d1","d2","d3","d4")

但我正在努力处理可能应该与此类似的第二部分(伪代码)

df <- data.frame(
  x = flatten(map(l, function(a) seq_along(a))),
  y = flatten(l),
  id = flatten(map(l, function(a) rep(a.name,times=length(a))))
)

从列表中构造数据框的正确方法是什么?或者有没有更好的方法来做到这一点?

更新:出于演示目的,可以想象 d1..d4 是

d1 <- pnorm(seq(-2, 2, 0.05))-3
d2 <- pnorm(seq(-3, 3, 0.10))
d3 <- pnorm(seq(-1, 2, 0.05))-4
d4 <- pnorm(seq(-4, 3, 0.15))

标签: rdataframe

解决方案


您可以定义一个接受任意数量向量的函数:

build_df <- function(...)
{
  vec_list <- list(...)
  df <- data.frame(x = do.call("c", sapply(vec_list, seq_along)),
                   y = do.call("c", vec_list),
                   name = do.call("c", sapply(seq_along(vec_list), 
                                              function(i) rep(names(vec_list)[i], 
                                                          length(vec_list[[i]]))))
             )
  rownames(df) <- seq(nrow(df))
  df
}

build_df(d1 = 1:3, d2 = 6:9, bananas = 4:6)
#>    x y    name
#> 1  1 1      d1
#> 2  2 2      d1
#> 3  3 3      d1
#> 4  1 6      d2
#> 5  2 7      d2
#> 6  3 8      d2
#> 7  4 9      d2
#> 8  1 4 bananas
#> 9  2 5 bananas
#> 10 3 6 bananas

reprex 包(v0.3.0)于 2020 年 8 月 3 日创建


推荐阅读