【问题标题】:element as the list names and list name as the element in a list?元素作为列表名称和列表名称作为列表中的元素?
【发布时间】:2014-04-09 14:42:14
【问题描述】:

我有一个向量列表(如下所示)。我想知道向量的每个元素在哪些列表元素中。换句话说,我想反转列表以创建一个新列表,其names 取自向量。

最好的方法是什么?

lst <- list(a=c(2, 3, 6, 10, 15, 17), b=c(4, 6, 9, 7, 6, 4, 3, 10), 
            c=c(9, 2, 1, 4, 3), d=c(3, 6, 17))
lst
$a
[1]  2  3  6 10 15 17

$b
[1]  4  6  9  7  6  4  3 10

$c
[1] 9 2 1 4 3

$d
[1]  3  6 17

我想得到以下答案。

$`1`
[1] "c"

$`10`
[1] "a" "b"

$`15`
[1] "a"

$`17`
[1] "a" "d"

$`2`
[1] "a" "c"

$`3`
[1] "a" "b" "c" "d"

$`4`
[1] "b" "b" "c"

$`6`
[1] "a" "b" "b" "d"

$`7`
[1] "b"

$`9`
[1] "b" "c"

【问题讨论】:

    标签: r


    【解决方案1】:

    这是stackunstack 的基本 R 方式:

    unstack(stack(lst), ind ~ values)
    # $`1`
    # [1] "c"
    # 
    # $`2`
    # [1] "a" "c"
    # 
    # $`3`
    # [1] "a" "b" "c" "d"
    # 
    # $`4`
    # [1] "b" "b" "c"
    # 
    # $`6`
    # [1] "a" "b" "b" "d"
    # 
    # $`7`
    # [1] "b"
    # 
    # $`9`
    # [1] "b" "c"
    # 
    # $`10`
    # [1] "a" "b"
    # 
    # $`15`
    # [1] "a"
    # 
    # $`17`
    # [1] "a" "d"
    

    【讨论】:

    • 巧妙地使用unstack。 +1
    • 我不太明白lapply(lst, as.vector) 的意义是什么。至少对于这个例子,你可以用 lst 替换它,并且什么都不会改变。
    • @Dason,那是因为不同的“Kevin”已经根据他们的口味编辑了这个问题,这使得现有的答案有点偏离。 jbaums 试图解决这个问题,但一定错过了你的观察。我敢肯定马修自己会注意到这一点。
    • @Dason 谢谢。我已经更新了答案。原始问题有一个矩阵列表。
    【解决方案2】:

    在使用来自“reshape2”的melt 之后,这是一种使用基础R 中的split 的方法:

    library(reshape2)
    x <- melt(lst)
    split(x$L1, x$value)
    # $`1`
    # [1] "c"
    # 
    # $`2`
    # [1] "a" "c"
    # 
    # $`3`
    # [1] "a" "b" "c" "d"
    # 
    # $`4`
    # [1] "b" "b" "c"
    # 
    # $`6`
    # [1] "a" "b" "b" "d"
    # 
    # $`7`
    # [1] "b"
    # 
    # $`9`
    # [1] "b" "c"
    # 
    # $`10`
    # [1] "a" "b"
    # 
    # $`15`
    # [1] "a"
    # 
    # $`17`
    # [1] "a" "d"
    

    同样,在带有stack 的基础 R 中:

    x <- stack(lapply(lst, c))
    split(as.character(x$ind), x$values)
    

    如果您使用的是“lst”而不是“lst”,甚至更直接:

    x <- stack(lst)
    split(as.character(x$ind), x$values)
    

    为了详细说明我的评论,我描述的更有效的方式是:

    split(rep(names(lst), lapply(lst, nrow)), unlist(lst, use.names = FALSE))
    

    应用于更大的lst,我们得到以下结果:

    fun1 <- function() split(rep(names(lst), lapply(lst, nrow)), unlist(lst, use.names = FALSE))
    fun2 <- function() { x <- stack(lapply(lst, c)) ; split(as.character(x$ind), x$values) }
    fun3 <- function() { x <- melt(lst) ; split(x$L1, x$value) }
    fun4 <- function() unstack(stack(lapply(lst, as.vector)), ind ~ values)
    
    ## Make lst much bigger
    lst <- unlist(replicate(10000, lst, simplify = FALSE), recursive=FALSE)
    names(lst) <- make.unique(names(lst))
    
    library(microbenchmark)
    
    system.time(fun3())
    #   user  system elapsed 
    # 48.338   0.000  47.643 
    
    microbenchmark(fun1(), fun2(), fun4(), times = 5)
    # Unit: milliseconds
    #   expr       min        lq   median        uq       max neval
    # fun1()  454.5913  456.6793  473.901  555.8954  574.4394     5
    # fun2()  922.1282 1028.4972 1034.872 1068.4761 1150.8072     5
    # fun4() 1222.5296 1300.0643 1323.253 1339.2037 1421.1546     5
    

    【讨论】:

    • 你好阿南达,谢谢。有用。但是如果 list.1 非常大,'melt' 似乎速度有点慢,对吧?你有更有效的方法吗?
    • @Kevin, stack 应该比melt 快,或者你可以使用repunlist
    • 谢谢阿难。你的答案就是我想要的。
    【解决方案3】:

    unlist list 获取向量中的所有数字。然后,使用这些数字拆分list 元素的names 向量。

    split( rep(names(lst),times=sapply(lst,length)),
             unlist(lst) )
    $`1`
    [1] "c"
    
    $`2`
    [1] "a" "c"
    
    $`3`
    [1] "a" "b" "c" "d"
    
    $`4`
    [1] "b" "b" "c"
    
    $`6`
    [1] "a" "b" "b" "d"
    
    $`7`
    [1] "b"
    
    $`9`
    [1] "b" "c"
    
    $`10`
    [1] "a" "b"
    
    $`15`
    [1] "a"
    
    $`17`
    [1] "a" "d"
    

    【讨论】:

    • 这与我的答案几乎相同,但使用length 而不是nrow(这是您问题原始版本的正确答案)。
    • 代码是一样的,但我更喜欢这个演示文稿。我应该更彻底地阅读你的答案。直到我发布答案后,我才找到fun1。不过没关系,您的更彻底的回答会适当地获得更多的选票,并且会保持在顶部。
    • 很抱歉,如果这令人困惑,但我不是发布问题的那个“凯文”。我编辑了原始问题,因为我很难阅读。
    • 没有注意到你不是同一个“凯文”。不过,您的编辑非常具有破坏性。另一个用户现在已经编辑了我的答案和接受的答案以匹配您对问题的编辑,同时假设您是 OP。为了便于阅读,对第一段的更改很好,但不确定现有答案所基于的更改代码。
    • 我现在意识到造成的破坏。对于那个很抱歉。经验教训。
    猜你喜欢
    • 2019-04-25
    • 1970-01-01
    • 2020-12-09
    • 2018-08-19
    • 2016-06-22
    • 2021-06-23
    • 2021-06-08
    • 2013-09-17
    • 1970-01-01
    相关资源
    最近更新 更多