【问题标题】:Subsetting columns of an R matrix contingent on a specific entry根据特定条目对 R 矩阵的列进行子集化
【发布时间】:2017-01-11 17:08:51
【问题描述】:

似乎这个问题应该被问过很多次,但我正在搜索Questions that may already have your answer,但没有成功。

如何使用布尔运算符(不使用subset())对矩阵的列进行子集化?

> m = matrix(c("A", "B", "B", "B", "C", "A", "C", "C", "D"), nrow = 3)
> m
     [,1] [,2] [,3]
[1,] "A"  "B"  "C" 
[2,] "B"  "C"  "C" 
[3,] "B"  "A"  "D" 

请注意,这些列没有名称,我希望 any 列在某些条目中包含值“D”。

例如,在this post 中,调用grades[grades[,"pass"] == 2,]。除了调用是提取行这一事实以及 pass 引用单个列这一事实之外,没有列的名称。

我试过了:

> m[m == "D", ]
Error in m[m == "D", ] : (subscript) logical subscript too long

> m[which(m=="D"), ]
Error in m[which(m == "D"), ] : subscript out of bounds

> m = as.data.frame(m) # Turning the matrix into a df
> m[m == "D", ]
     V1   V2   V3
NA <NA> <NA> <NA>

【问题讨论】:

    标签: r matrix subset


    【解决方案1】:

    您可以使用apply 调用来搜索列元素并为其编制索引。

    m[,apply(m, MARGIN = 2, function(x) any(x == "D")), drop = FALSE]
    
         [,1]
    [1,] "C" 
    [2,] "C" 
    [3,] "D" 
    

    注意 - 您会注意到存在 drop = FALSE 参数。这是为了确保在只有 1 列的情况下输出仍然是矩阵。

    【讨论】:

    • 谢谢。这是一种痛苦的子集化方式。请不要误认为这是批评,因为您很可能是正确的 - R 并不是特别容易...MARGIN = 2 引入了我们想要列的概念?
    • 正确,MARGIN 表示是否超过行或列。您可以在文档中看到这一点。
    • @Toni,如果这满足您的问题,请务必接受此答案。
    【解决方案2】:

    这是另一种选择。

    m[, colSums(m == "D") > 0, drop=FALSE]
         [,1]
    [1,] "C" 
    [2,] "C" 
    [3,] "D" 
    

    m==D 构造一个逻辑矩阵,然后colSums 计算 TRUE 的数量。接下来,检查这些是否大于 0。该检查的结果用于对矩阵进行子集化。按照@cdeterman 的回答,我添加了 drop=FALSE 以保留矩阵结构。

    【讨论】:

    • 真的很优雅!谢谢!
    猜你喜欢
    • 2018-08-07
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 2020-07-14
    • 1970-01-01
    相关资源
    最近更新 更多