【问题标题】:split array into subarrays将数组拆分为子数组
【发布时间】:2015-09-02 13:51:58
【问题描述】:

我有一个数组,例如arr = cbind(c(1,1,2,2,3), c(1,2,3,4,5)),我想聚合具有相同第一个元素的行,并将结果存储为列表。有什么方法可以做到这一点?此示例的预期输出result = list( cbind(c(1,1), c(1,2)), cbind(c(2,2), c(3,4)), cbind(c(3), c(5)) )

【问题讨论】:

    标签: r matrix split


    【解决方案1】:

    我们可以循环(lapply)通过arr 的第一列的unique 值,并根据第一列的匹配元素与唯一元素对行进行子集化。

    lapply(unique(arr[,1]), function(i) arr[arr[,1]==i,,drop=FALSE])
    

    或者我们split'arr'的行序列和'arr'的第一列,并使用行索引来子集'arr'。

    lapply(split(1:nrow(arr), arr[,1]), function(i) arr[i,, drop=FALSE])
    

    或者正如 @Jota 在 cmets 中提到的那样,我们可以 split 第一列的“arr”将 vector 作为 list 元素。我们使用lapply 循环并将vector 转换为matrix

    lapply(split(arr, arr[,1]), matrix, ncol=2)
    

    基准测试

    arr1 <- cbind(rep(seq(1000), each=1000), seq(1e6))
    system.time(res1 <- lapply(unique(arr1[,1]), function(i) 
                    arr1[arr1[,1]==i,,drop=FALSE]))
    # user  system elapsed 
    # 18.980   0.000  15.906 
    
    
    system.time(res2 <- lapply(split(1:nrow(arr1), arr1[,1]), 
                      function(i) arr1[i,, drop=FALSE]))
    #  user  system elapsed 
    #   0.00    0.00    0.07 
    names(res2) <- NULL
     identical(res1, res2)
    #[1] TRUE
    
    system.time(res3 <- lapply(split(arr1, arr1[,1]), matrix, ncol=2))
    # user  system elapsed 
    #  0.000   0.000   0.186 
    names(res3) <- NULL
    identical(res1, res3)
    #[1] TRUE
    
    system.time(res4 <- split(data.frame(arr1), arr1[,1]))
    #  user  system elapsed 
    #  1.151   0.000   1.039 
    

    基于上述基准,split 方法更好。

    【讨论】:

    • lapply(split(arr, arr[,1]), matrix, ncol=2) 是类似的策略。
    • @Jota 谢谢,很简洁。
    【解决方案2】:

    为什么不采用这种更短的方法:

    split(data.frame(arr), arr[,1])
    #$`1`
    #  X1 X2
    #1  1  1
    #2  1  2
    
    #$`2`
    #  X1 X2
    #3  2  3
    #4  2  4
    
    #$`3`
    #  X1 X2
    #5  3  5
    

    【讨论】:

    • 好吧,您的较短方法是 data.frame 而不是矩阵作为列表元素。根据 OP 提供的预期输出,它仍然是一个矩阵。
    猜你喜欢
    • 2018-04-18
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多