【问题标题】:Named arrays, dataframes and matrices命名数组、数据框和矩阵
【发布时间】:2015-05-08 11:27:21
【问题描述】:

如果我像这样根据另一个向量y 中的类标签将我的数据矩阵分成几行,结果是这样的“名称”:

> X <- matrix(c(1,2,3,4,5,6,7,8),nrow=4,ncol=2)
> y <- c(1,3,1,3)
> X_split <- split(as.data.frame(X),y)
$`1`
  V1 V2
1  1  5
3  3  7

$`3`
  V1 V2
2  2  6
4  4  8

我想遍历结果并对每个矩阵进行一些操作,例如对元素求和或对列求和。如何在循环中访问每个矩阵,这样我才能做到这一点?

labels = names(X_split)
for (k in labels) {
    # How do I get X_split[k] as a matrix?
    sum_class = sum(X_split[k]) # Doesn't work
}

事实上,我根本不想处理数据帧和命名数组。有没有办法我可以在没有as.data.frame 的情况下调用split 并获取矩阵列表或类似的东西?

【问题讨论】:

    标签: r


    【解决方案1】:

    在不转换为数据框的情况下进行拆分

    X_split <- list(X[c(1, 3), ], X[c(2, 4), ]) 
    

    更一般地说,要写成长度为nrow(X)的向量y,表示每一行所属的组,你可以写成

    X_split <- lapply(unique(y), function(i) X[y == i, ])
    

    总结结果

    X_sum <- lapply(X_split, sum)
    
    # [[1]]
    # [1] 16
    
    # [[2]]
    # [1] 20
    

    (如果要将结果作为向量,则使用sapply

    【讨论】:

    • 我的y怎么写?
    • lapply(unique(y), function(i) X[y == i, ]) 会循环遍历数组多次(每个唯一的y 一次)而不是一次,不是吗?
    • 它遍历unique(y)(在本例中为c(1,3))而不是X,因此它根本不会通过数组。但它会返回 X 的每个子索引部分的副本,如果这是您所要求的(就像 split 一样)。
    • 我的意思是每次调用X[y == i, ] 都需要单独通过y 才能找到匹配的索引,这似乎是多余的,因为拆分可以在y 上的单个循环中完成。
    • 确实如此,但为什么会出现问题?如果您的矩阵 X 非常大,这只会是一个问题,在这种情况下,真正的瓶颈将是创建副本而不是 y==i 部分(如果您有一个大矩阵,您不应该使用 @987654339 @反正,前面提到的data.table效率更高)
    【解决方案2】:

    另一种选择是不首先拆分,而是按y 求和。这是一种可能的data.table 方法

    library(data.table)
    as.data.table(X)[, sum(sapply(.SD, sum)), by = y]
    #    y V1
    # 1: 1 16
    # 2: 3 20
    

    【讨论】:

    • 除了求和之外,我还需要对每个矩阵进行其他操作(抱歉,我已经编辑了问题)。基本上我只是想在循环的每次迭代中将矩阵提取为矩阵,但我不知道该怎么做。
    【解决方案3】:

    可以肯定直接在矩阵上操作是最有效的:

    tapply(rowSums(X),y,sum)
    #  1  3 
    # 16 20 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-10
      • 2020-05-10
      • 2021-02-09
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      相关资源
      最近更新 更多