Fel*_*x M 6 collections r list purrr
我有一个这样构建的列表:
x <- list(id = c("a", "b"),
value = c(1,2),
othervalue = c(3,4)
)
Run Code Online (Sandbox Code Playgroud)
我需要将列表转换为如下结构:
y <- list(a = list(value = 1, othervalue = 3),
b = list(value = 2, othervalue = 4)
)
Run Code Online (Sandbox Code Playgroud)
你会怎么做?
编辑:
我偶然发现了这个问题的更高级版本:
这里的输出中有某种嵌套列表。
x <- list(id = c("a", "b", "a"), key = c("foo", "foo", "bar"), value = c(1, 2, 3))
Run Code Online (Sandbox Code Playgroud)
到
y <- list(a = list(foo = 1, bar = 2), b = list(foo = 3))
Run Code Online (Sandbox Code Playgroud)
根据目前的答案,结果是:
$a
$a$key
[1] "foo"
$a$value
[1] 1
$b
$b$key
[1] "foo"
$b$value
[1] 2
$a
$a$key
[1] "bar"
$a$value
[1] 3
Run Code Online (Sandbox Code Playgroud)
您可以list与Map一起使用do.call。
z <- setNames(do.call(Map, c(list, x[-1])), x[[1]])\n\nidentical(z, y)\n#[1] TRUE\nRun Code Online (Sandbox Code Playgroud)\n相同但使用管道:
\nz <- c(list, x[-1]) |>\n do.call(what=Map) |>\n setNames(x[[1]])\nRun Code Online (Sandbox Code Playgroud)\n基准
\nx <- list(id = c("a", "b"), value = c(1,2), othervalue = c(3,4) )\n\nbench::mark(purr = purrr::transpose(x[-1], .names = x[[1]]), #@Ma\xc3\xabl\n lapplySplit = lapply(split(as.data.frame(x)[-1], x$id), c), #@Allan Cameron\n Map = setNames(do.call(Map, c(list, x[-1])), x[[1]]) ) #@GKi\n\n# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc\n# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl>\n#1 purr 2.51ms 2.64ms 372. 3.69MB 34.2 152 14\n#2 lapplySplit 461.77\xc2\xb5s 490.48\xc2\xb5s 2018. 102.21KB 52.0 892 23\n#3 Map 14.13\xc2\xb5s 15.9\xc2\xb5s 61557. 3.06KB 80.1 9987 13\nRun Code Online (Sandbox Code Playgroud)\n在这种情况下,与第二个 lapplySplit 相比,Map 的速度大约快 30 倍,并且分配的内存要少得多。
\n以及来自 @s_baldur 的数据集:
x <- list(id = c(letters, LETTERS), value = 1:52, othervalue = (1:52 + 100))\nbench::mark(check=FALSE,\npurr = purrr::transpose(x[-1], .names = x[[1]]), #@Ma\xc3\xabl\nlapplySplit = lapply(split(as.data.frame(x)[-1], x$id), c), #@Allan Cameron\nMap = setNames(do.call(Map, c(list, x[-1])), x[[1]]) ) #@GKi\n# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc\n# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl>\n#1 purr 2.5ms 2.59ms 385. 3.69MB 33.9 159 14\n#2 lapplySplit 2.43ms 2.51ms 391. 137.21KB 68.3 149 26\n#3 Map 50.98\xc2\xb5s 61.06\xc2\xb5s 15717. 3.51KB 72.5 6506 30\nRun Code Online (Sandbox Code Playgroud)\n对于更新的问题,可能使用:
\nlapply(split(setNames(x$value, x$key), x$id), as.list)\nRun Code Online (Sandbox Code Playgroud)\n但有必要吗list?如果没有,那么可以使用:
split(setNames(x$value, x$key), x$id)\nRun Code Online (Sandbox Code Playgroud)\n
你可以做
lapply(split(as.data.frame(x)[-1], x$id), c)
#> $a
#> $a$value
#> [1] 1
#>
#> $a$othervalue
#> [1] 3
#>
#>
#> $b
#> $b$value
#> [1] 2
#>
#> $b$othervalue
#> [1] 4
Run Code Online (Sandbox Code Playgroud)
与以下内容相同y:
identical(lapply(split(as.data.frame(x)[-1], x$id), c), y)
#> [1] TRUE
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
136 次 |
| 最近记录: |