如何转换data.frame
df <- data.frame(id=c("af1", "af2"), start=c(100, 115), end=c(114,121))
到列表列表
LoL <- list(list(id="af1", start=100, end=114), list(id="af2", start=115, end=121))
我尝试过像
这样的事情not.LoL <- as.list(as.data.frame(t(df)))
我真的不确定在此之后我最终会得到什么,但这不太对劲。我的要求是我可以通过命令
访问第一个start
> LoL[[1]]$start
[1] 100
我目前拥有的not.LoL
给了我以下错误:
> not.LoL[[1]]$start
Error in not.LoL[[1]]$start : $ operator is invalid for atomic vectors
非常感谢解释和/或解决方案。
编辑:我应该清楚地说明这里的“id”实际上是非唯一的 - 在一个ID下可以有多个元素。因此,我可以使用不依赖split
的唯一ID的解决方案。
答案 0 :(得分:7)
使用plyr
,您可以执行此操作
dlply(df,.(id),c)
要避免按ID分组,如果有多个(可能需要更改列名,id对我来说是唯一的)
dlply(df,1,c)
答案 1 :(得分:6)
LMAo <- lapply(split(df,df$id), function(x) as.list(x)) # is one way
# more succinctly
# LMAo <- lapply(split(df,df$id), as.list)
根据您的评论编辑的解决方案:
lapply( split(df,seq_along(df[,1])), as.list)
答案 2 :(得分:5)
您可以使用apply
将数据框转换为以下列表:
LoL <- apply(df,1,as.list)
但是,这会将所有数据更改为文本,因为它会将单个原子向量传递给函数。
答案 3 :(得分:0)
在基本R中,使用mapply
而不是split
或lapply
的速度要快得多-但是,您必须通过do.call
来调用它,以便每一列单独使用。
df <- sleep
f <- function(df) {
lapply(seq_len(nrow(df)), function(row) {
df[row, , drop = FALSE]
})
}
f2 <- function(df) {
do.call("mapply", c(list, df, SIMPLIFY = FALSE, USE.NAMES=FALSE))
}
f3 <- function(df) {
split(df, seq(nrow(df)))
}
microbenchmark::microbenchmark(f(df), f2(df), f3(df))
#> Unit: microseconds
#> expr min lq mean median uq max neval
#> f(df) 573.799 607.8375 759.1721 626.0095 752.9465 2861.961 100
#> f2(df) 114.819 123.5190 155.5185 129.9210 141.4340 1375.573 100
#> f3(df) 598.774 625.6025 813.6837 634.5855 684.3825 11230.678 100
由reprex package(v0.3.0)于2019-10-09创建
答案 4 :(得分:0)
如果像我一样,您主要是想创建要在highcharter
中使用的列表的列表,则该软件包包含函数list_parse()
(如果要删除名称,则包含list_parse2()
) )。像这样简单地使用它:
library(highcharter)
df <- data.frame(id=c("af1", "af2"), start=c(100, 115), end=c(114,121))
LoL <- list_parse(df)
之后,您可以进行所需的索引编制:
> LoL[[1]]$start
[1] 100