折叠矩阵以矢量化并用列名替换值

时间:2018-12-12 21:22:02

标签: r matrix

有一个像这样的矩阵:

m <- matrix(c(F,T,F,T,F,T,F,T,F, F,F,T,F,T,F,T,F,T), nrow=9, ncol=2,
           dimnames=list(c(), c('1x2x24','2x2x24')))

    1x2x24 2x2x24
[1,]  FALSE  FALSE
[2,]   TRUE  FALSE
[3,]  FALSE   TRUE
[4,]   TRUE  FALSE
[5,]  FALSE   TRUE
[6,]   TRUE  FALSE
[7,]  FALSE   TRUE
[8,]   TRUE  FALSE
[9,]  FALSE   TRUE

大概每行只有一个TRUE。获得这样的向量的最佳方法是什么:

NA, 1x2x24, 2x2x24, 1x2x24, 2x2x24, 1x2x24, 2x2x24, 1x2x24, 2x2x24

一种获取方法是用列名替换每个列中的每个TRUE,并用NA或“”替换每个FALSE。然后使用paste()合并行中的所有列。我不太确定该怎么做。我们非常感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

如果我们将矩阵乘以1:2,则与在结尾处可重复使用的输入矩阵m相同,这与将每一行乘以1:2相同,即得出长度与行数,如果该行中没有TRUE值,则每个元素为0;如果该行的第一列中为TRUE值,则为1;如果该行第二列中为TRUE值,则为2。向其添加1并索引到一个三元组,该三元组的第一个元素为NA,随后的元素为列名。

c(NA, colnames(m))[m %*% 1:2 + 1]
## [1] NA       "1x2x24" "2x2x24" "1x2x24" "2x2x24" "1x2x24" "2x2x24" "1x2x24"
## [9] "2x2x24"

或者,我们可以使用相同的计算,但可以使用它来定义要转换为字符串的因子:

as.character(factor(m %*% 1:2 + 1, lab = c(NA, colnames(m))))

如果事实证明一行中可能有两个TRUE值,那么对于此类行,计算得出4,所以只需将c(NA, colnames(m))替换为c(NA, colnames(m), "both")

注意

m <- structure(c(FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, 
FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE
), .Dim = c(9L, 2L), .Dimnames = list(c("[1,]", "[2,]", "[3,]", 
"[4,]", "[5,]", "[6,]", "[7,]", "[8,]", "[9,]"), c("1x2x24", 
"2x2x24")))

答案 1 :(得分:1)

使用coalesce函数将所有dplyr的值转换为FALSE后,我就使用了包NA中的函数ifelse。这不是最干净的方法,但是可以。为了完整起见:如果尚未安装dplyr,则需要先运行install.packages("dplyr")

library(dplyr)

X <- matrix(c(F,T,F,T,F,T,F,T,F, F,F,T,F,T,F,T,F,T), nrow=9, ncol=2,
            dimnames=list(c(), c('1x2x24','2x2x24')))
> X
      1x2x24 2x2x24
 [1,]  FALSE  FALSE
 [2,]   TRUE  FALSE
 [3,]  FALSE   TRUE
 [4,]   TRUE  FALSE
 [5,]  FALSE   TRUE
 [6,]   TRUE  FALSE
 [7,]  FALSE   TRUE
 [8,]   TRUE  FALSE
 [9,]  FALSE   TRUE

# Here we can use ifelse to turn F into NA
#> ifelse(X[,1]==F, NA_integer_, colnames(X)[1])
#[1] NA       "1x2x24" NA       "1x2x24" NA       "1x2x24" NA       "1x2x24" NA      

#> ifelse(X[,2]==F, NA_integer_, colnames(X)[2])
#[1] NA       NA       "2x2x24" NA       "2x2x24" NA       "2x2x24" NA       "2x2x24"


y<-as.character(data.frame(ifelse(X[,1]==F, NA_integer_, colnames(X)[1]))[,1])
z<-as.character(data.frame(ifelse(X[,2]==F, NA_integer_, colnames(X)[2]))[,1])

coalesce(y,z)
[1] NA       "1x2x24" "2x2x24" "1x2x24" "2x2x24" "1x2x24" "2x2x24" "1x2x24" "2x2x24"

答案 2 :(得分:1)

这应该有效

C1<-c(FALSE,FALSE,FALSE,FALSE,
   TRUE,FALSE,FALSE,TRUE, 
   TRUE,FALSE,FALSE,TRUE,
   TRUE,FALSE,FALSE,TRUE, 
   TRUE,FALSE,FALSE,TRUE)
print(C1)
m<-matrix(C1,ncol=2)
colnames(m)<-c("1x2x24","2x2x24")
vector_result<-(apply(m, 1, 
function(u) paste(names(which(u)), collapse="NA" ) 
))
idx<-(which(vector_result=="")) # replace "" with NA     
vector_result[idx]="NA"
print(vector_result)

答案 3 :(得分:1)

我们可以使用

apply(m,1,function(x) names(which(x))[1])
# [1,]     [2,]     [3,]     [4,]     [5,]     [6,]     [7,]     [8,]     [9,]  
#   NA "1x2x24" "2x2x24" "1x2x24" "2x2x24" "1x2x24" "2x2x24" "1x2x24" "2x2x24"