R - 根据数据框的变量和另一个矩阵的值对矩阵进行子集化

R - Subset a matrix in function of a variable from data frame and values of an other matrix

几天以来,我一直在寻找在 R 中管理数据的方法。我有相同的一组个体 (n=5013),其结构如下:两个不对称邻接矩阵(m1m2)(nxn方矩阵,其中所有个体组成矩阵的行和列)和一个数据框(df),其中包含我的一组个体(df$N)和一个变量(df$V).

我正在搜索使用变量 df$V(行和列的不同 criteria/variable 值)和子集 m1(或识别无效情况)对矩阵进行子集化的方法m2 的单元格值的函数。

下面的例子说明了我的问题:

# N are individuals. Two matrices (m1 and m2) and a dataframe (df) with a variable (df$V)
> df
  N  V
1 a v1
2 b v2
3 c v3
4 d v1
5 e v2
6 f v3
7 g v1

> m1
  a b c d e f g
a 7 3 9 8 1 6 8
b 1 6 9 2 9 4 4
c 2 3 2 7 9 7 3
d 9 7 6 3 2 6 6
e 9 9 6 5 5 6 5
f 1 1 1 6 1 5 9
g 6 2 5 2 1 8 5

> m2
  a b c d e f g
a 8 3 7 8 4 3 2
b 2 8 4 2 7 7 2
c 8 3 1 6 9 9 4
d 7 3 6 7 4 9 5
e 5 8 7 1 7 6 6
f 9 6 8 9 6 6 2
g 4 8 8 1 9 7 3

例如,我在 df$V

中对矩阵中的单元格进行子集化,其中行取值“v1”和“v3”,cols 取值“v2”
> m1subseted
  b e
a 3 1
c 3 9
d 7 2
f 1 1
g 2 1
> m2subseted
  b e
a 3 4
c 3 9
d 3 4
f 6 6
g 8 9

然后在 m1 子集中的观察值(或识别无效案例)在 m2 子集中的单元格值“<5”。我正在搜索的结果:一个矩阵,m1 的子集。

#subset m1 if cell value in m2 is <5 / Invalid cells = NA
  b e
a 3 1
c 3 NA
d 7 2
f NA NA
g NA NA

可重现的数据

m1 <- as.matrix(data.frame(a = sample(1:10, size = 7),
                 b= sample(1:10, size = 7),
                 c=sample(1:10, size = 7),
                 d=sample(1:10, size = 7),
                 e=sample(1:10, size = 7),
                 f=sample(1:10, size = 7),
                 g=sample(1:10, size = 7)))
                 rownames(m1)<-colnames(m1)


m2 <- as.matrix(data.frame(a = sample(1:10, size = 7),
                 b= sample(1:10, size = 7),
                 c=sample(1:10, size = 7),
                 d=sample(1:10, size = 7),
                 e=sample(1:10, size = 7),
                 f=sample(1:10, size = 7),
                 g=sample(1:10, size = 7)))
                 rownames(m2)<-colnames(m2)



df <- data.frame(N = as.factor(letters[1:7]), 
       V = c("v1","v2","v3","v1","v2","v3","v1"))

评论

@jkt 提出的解决方案工作正常,除非标签很复杂(带有重音符号、括号等),就像在我的原始数据集中一样。我找到的解决方案是在应用算法之前用最简单的标签更改复杂的标签,并在结果上恢复原始标签。 我分享了我使用的代码与@jkt 提供的解决方案(改编为示例),希望它对某人有用。

#Create new labels. In this case are numbers, where 7 
#correspond to the dimmensions of matrices and observations on df
new.code.labels<-c(1:7)
#Create new col/variable on df
df$TempLabel<-new.code.labels
#Recode rows and cols on matrices
rownames(m1)<-new.code.labels
colnames(m1)<-new.code.labels
rownames(m2)<-new.code.labels
colnames(m2)<-new.code.labels

#Apply algorithm proposed by @jkt
crit1 <- c('v1','v3')
crit2 <- 'v2'
#Observe I use new labels on dataframe (df$TempLabel)
m11 <- m1[df$TempLabel[which(df$V %in% crit1)], df$TempLabel[which(df$V %in% crit2)]]
m21 <- m2[df$TempLabel[which(df$V %in% crit1)], df$TempLabel[which(df$V %in% crit2)]]
m11[!(m21<5)] <- NA
m11

#To regain the original labels on results
row.coded.labels.result<-rownames(m11)
df.subseted.by.result.row<-subset(df, df$TempLabel %in% row.coded.labels.result)
rownames(m11)<-df.subseted.by.result.row$N

col.coded.labels.result<-colnames(m11)
df.subseted.by.result.col<-subset(df, df$TempLabel %in% col.coded.labels.result)
colnames(m11)<-df.subseted.by.result.col$N
m11

我只会使用一系列子集命令。

这定义了两个标准(基于 v1、v3 和 v2):

crit1 <- c('v1','v3')
crit2 <- 'v2'

这根据条件和相应的 row/column 名称对矩阵进行子集化:

m11 <- m1[df$N[which(df$V %in% crit1)], df$N[which(df$V %in% crit2)]]
m21 <- m2[df$N[which(df$V %in% crit1)], df$N[which(df$V %in% crit2)]]

这会在第二个子集矩阵中设置所有不符合最后一个条件的值 NA

m11[!(m21<5)] <- NA

调用 m11 然后给你:

   b  e
a  3  1
c  3 NA
d  7  2
f NA NA
g NA NA

你可以把它变成一个函数,把你所有的标准作为参数加上矩阵和数据框。