【问题标题】:Subset of data frame by a data frame of indexes索引数据帧的数据帧子集
【发布时间】:2021-02-02 23:50:26
【问题描述】:

我想选择以下数据框的具体值:

src:
   c1 c2 c3 c4 c5 c6
rA  9 12 44 88 11  1
rB 12  7 14 24 48 67
rC  0 15 97 17 13 18
rD 74 51 10 11 14  8

通过存储在具有相同列名和行名作为值的数据框中的索引:

idx:
   c1 c4 c6
 1 rA rD rA
 2 rD rA rB
 3 rB rC rC

所以结果应该是这样的:

res:
    1  2  3
 1  9 11  1
 2 74 88 67
 3 12 17 18

请问最优雅的方法是什么?

【问题讨论】:

  • 为什么问题收到负面评价?我希望以评论的形式提供反馈,以便我可以改进问题或防止将来出现同样的错误。谢谢!
  • 请考虑使用dput提供可重复的示例

标签: r dataframe subset


【解决方案1】:

给定的原始帧是这样定义的:

src <- data.frame(matrix(c(9, 12, 44, 88, 11, 1,
                           12, 7, 14, 24, 48, 67,
                           0, 15, 97, 17, 13, 18,
                           74, 51, 10, 11, 14, 8), nrow = 4, byrow = TRUE))
rownames(src) <- paste0("r", LETTERS[1:4])
colnames(src) <- paste0("c", 1:6)

idx <- data.frame(matrix(c("rA", "rD", "rB",
                           "rD", "rA", "rC",
                            "rA", "rB", "rC"), nrow = 3),
                  stringsAsFactors = FALSE)
colnames(idx) <- c("c1", "c4", "c6")

可以用sapply解决:

sapply(colnames(idx), function(col) {
  src[idx[, col], col]
})

它产生一个具有预期结果的矩阵:

     c1 c4 c6
[1,]  9 11  1
[2,] 74 88 67
[3,] 12 17 18

【讨论】:

    【解决方案2】:

    这是一种使用match的方法:

    result <- idx
    result[] <- src[cbind(match(unlist(idx), rownames(src)), 
                          match(names(idx)[col(idx)], names(src)))]
    result
    
    #  c1 c4 c6
    #1  9 11  1
    #2 74 88 67
    #3 12 17 18
    

    这里的逻辑是创建一个包含两列的矩阵,第一列是行号,第二列是列号,以便从中提取数据。

    【讨论】:

      猜你喜欢
      • 2019-08-12
      • 2012-11-17
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      相关资源
      最近更新 更多