2017-01-11 48 views
0

似乎应该问这个问题一堆,但我正在搜索Questions that may already have your answer没有成功。在特定条目上设置R矩阵的子列

你如何用布尔运算符子集(不使用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" 

注意,列没有名字,我想包含在某些条目中的值“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> 

回答

1

以下是另一种选择。

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

m==D构建一个逻辑矩阵,则colSums计数TRUEs的数量。接下来,检查这些是否大于0.检查的结果用于矩阵的子集。在@ cdeterman的回答之后,我添加了drop = FALSE来保留矩阵结构。

+0

真高雅!谢谢! – Toni

2

您可以使用apply呼叫搜索的列元素和索引这些。

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

    [,1] 
[1,] "C" 
[2,] "C" 
[3,] "D" 

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

+0

谢谢。这是对它进行子集化的一种痛苦方式。请不要将此误解为批评,因为您可能很正确 - R并非特别容易...... MARGIN = 2'引入了我们想要列的概念? – Toni

+0

正确,'MARGIN'表示是否在行或列上。你可以在文档中看到这个。 – cdeterman

+0

@Toni,如果这符合你的问题,请务必接受这个答案。 – cdeterman