可以使数据框接受列表作为行吗?

Can a data frame be made to accept alists as rows?

考虑

items<-alist(2^1,2^2,2^3,2^3)

假设我想构建一个数据框,其中 items 中未评估的表达式是一列,而它们的评估版本在另一列中。换句话说,我想要这样的东西:

items           results
2^1                   1
2^2                   4
2^3                   8
2^3                   8

作为我的输出。我会使用 row.names 参数,但它拒绝重复的名称,否则无法说服。

自然要尝试的是

items<-alist(2^1,2^2,2^3,2^3)
outs<-sapply(items,eval)
data.frame(items=items,results=outs)

但输出似乎将 alist 的每个元素视为列名:

> data.frame(items=items,results=outs)
  items.2.1 items.2.2 items.2.3 items.2.3.1 results
1         2         4         8           8       2
2         2         4         8           8       4
3         2         4         8           8       8
4         2         4         8           8       8

lapply 不公平:

> outs<-lapply(items,eval)
> data.frame(items=items,results=outs)
  items.2.1 items.2.2 items.2.3 items.2.3.1 results.2 results.4 results.8 results.8.1
1         2         4         8           8         2         4         8           8

我知道我可以使用矩阵而不是数据框,但这不是我要问的。

@nicola 在评论中的建议几乎有效,但显示不正确:

> data.frame(items=I(items),results=vapply(items,eval,1))
    items results
1 ^, 2, 1       2
2 ^, 2, 2       4
3 ^, 2, 3       8
4 ^, 2, 3       8

如果你不关心显示,我会用它。如果你想让它很好地显示,你需要将语言对象转换为表达式对象,例如

eitems <- lapply(items, as.expression)
> data.frame(items=I(eitems),results=vapply(items,eval,1))
  items results
1   2^1       2
2   2^2       4
3   2^3       8
4   2^3       8

或者如果您不想再次计算它们,则将它们分解为字符值:

ditems <- sapply(items, deparse)
> data.frame(items = ditems, results=vapply(items,eval,1))
  items results
1   2^1       2
2   2^2       4
3   2^3       8
4   2^3       8