将大型列表融入长格式[有效]

时间:2017-10-24 21:54:04

标签: r list reshape

我使用以下格式获得了大list

example <- list("12908430751", "12908453145", c("12908453145","12908472085","453145472085"), c("12908453145", "12908472085", "453145472085"), "12908453145", c("12908453145", "12908472085", "453145472085"))

example
[[1]]
[1] "12908430751"

[[2]]
[1] "12908453145"

[[3]]
[1] "12908453145"  "12908472085"  "453145472085"

[[4]]
[1] "12908453145"  "12908472085"  "453145472085"

[[5]]
[1] "12908453145"

[[6]]
[1] "12908453145"  "12908472085"  "453145472085"

虽然使用library(reshape2); melt(example)适用于较小的数据集,但实际数据(约600万个元素)需要很长时间。我想知道是否有更有效的方法来实现这一点。

Output
      value     L1
1   12908430751  1
2   12908453145  2
3   12908453145  3
4   12908472085  3
5  453145472085  3
6   12908453145  4
7   12908472085  4
8  453145472085  4
9   12908453145  5
10  12908453145  6
11  12908472085  6
12 453145472085  6

我发现类似的Melt data.frame containing list to long format (efficiently),但未能适应我的情况。

RESULT

谢谢大家,我只是快速检查了我的列表example1,其中有100万个元素

system.time({foo <- unlist(lapply(example1, function(x) length(x)))
result <- data.frame(value = unlist(example1), 
L1 = unlist(sapply(1:length(foo), function(x) rep(x, foo[x]))))})

用户系统已用完 9.63 0.10 9.73

system.time({
df <- structure(list(value = example1 , id = 1:length(example1)), .Names = 
c("value", "L1"), row.names = 1:length(example), class = "data.frame")
result1 <- setDT(df)[, .(value = unlist(value)), by = .(L1)]})

用户系统已用完 1.25 0.00 1.26

system.time({result3 <- tibble(L1 = 1:length(example1), value = example1) %>% unnest()})

用户系统已用完 5.99 0.00 5.98

system.time({ stack(setNames(example1, seq_along(example)))})

用户系统已用完 1.08 0.00 1.08

无法让并行版本以结果结束,但可能就在我身边。虽然我没有定义效率,但我采用最快的方法。

4 个答案:

答案 0 :(得分:2)

如果你四处寻找可能有更快的方法,但是基础R有stack可以很快地运行:

stack(setNames(example, seq_along(example)))

#         values ind
#1   12908430751   1
#2   12908453145   2
#3   12908453145   3
#4   12908472085   3
#5  453145472085   3
#6   12908453145   4
#7   12908472085   4
#8  453145472085   4
#9   12908453145   5
#10  12908453145   6
#11  12908472085   6
#12 453145472085   6

它的内部基本上是unlist,然后重复names(x)的每个值,相应的lengths(x)次。请参阅utils:::stack.default以阅读代码。

答案 1 :(得分:0)

您可以在不费力的情况下使用parallel看到改进

library(parallel)
library(dplyr)
library(reshape2)
library(data.table)  # for rleid

cl <- makeCluster(detectCores())   # automatically detect number of cores
clusterEvalQ(cl, { library(reshape2) })  # need to export package to workers

# Split your data into chunks
nchunks <- 2   # does not need to equal number of cores (can be > # of cores but should be close to number of cores)
chunks <- split(example, cut(seq_along(example), nchunks))
result <- parLapply(cl, chunks, function(i) { melt(i) })
stopCluster(cl)

# combine back into data.frame
df <- Reduce("rbind", result)
answer <- df %>%
        mutate(L1 = rleid(L1))

输出

          value L1
1   12908430751  1
2   12908453145  2
3   12908453145  3
4   12908472085  3
5  453145472085  3
6   12908453145  4
7   12908472085  4
8  453145472085  4
9   12908453145  5
10  12908453145  6
11  12908472085  6
12 453145472085  6

答案 2 :(得分:0)

如果您愿意使用tidyverse方法,那么如何制作一个tibble然后unnest(我不确定这对您的用例有多高效) ):

library(tidyverse)

tibble(L1 = 1:length(example), value = example) %>% unnest()

#> # A tibble: 12 x 2
#>       L1        value
#>    <int>        <chr>
#>  1     1  12908430751
#>  2     2  12908453145
#>  3     3  12908453145
#>  4     3  12908472085
#>  5     3 453145472085
#>  6     4  12908453145
#>  7     4  12908472085
#>  8     4 453145472085
#>  9     5  12908453145
#> 10     6  12908453145
#> 11     6  12908472085
#> 12     6 453145472085

答案 3 :(得分:0)

你可能想试试这个:

df <- structure(list(value = example , id = 1:length(example)), .Names = c("value", "L1"), 
            row.names = 1:length(example), class = "data.frame")

library(data.table)
setDT(df)[, .(value = unlist(value)), by = .(L1)]

##     L1        value
##  1:  1  12908430751
##  2:  2  12908453145
##  3:  3  12908453145
##  4:  3  12908472085
##  5:  3 453145472085
##  6:  4  12908453145
##  7:  4  12908472085
##  8:  4 453145472085
##  9:  5  12908453145
## 10:  6  12908453145
## 11:  6  12908472085
## 12:  6 453145472085
相关问题