考虑以下数据集:
set.seed(50)
d = matrix(rbinom(1000, 1, 0.9), ncol = 20)
每行对应一个对象,每列对应一个 测量物体。例如,行可以是a中的个体 研究和专栏可以通过时间重复测量。在这 例如,测量值为TRUE / FALSE表示存在或不存在 对象
我正在寻找一种能让我识别出来的算法
具有n
重合观测值的行的最大集合。
换句话说,我正在寻找一种过滤所有行的方法
在同一列中有n
个TRUE值。该组的成员可以
但有超过n
个真值。
简单示例:具有20(全部)TRUE值的行由
捕获which(apply(d, 1, all))
标识行3, 10, 12, 24, 36, 39, 48, 50
。同样,它是
易于识别所有独特序列并识别共享的组
同样的观察:
unique.series = d[which(!duplicated(d)),]
groups = vector("list", nrow(unique.series))
for(i in seq_along(groups))
groups[[i]] = which(apply(d, 1, function(x)
identical(x, unique.series[i,])))
但是,如果我希望所有群体观察到19个或更多,该怎么办?例如,
群组3
(行3, 10, 12, 24, 36, 39, 48, 50
)和21
(行23, 32, 40
)仅因观察9
而异
(第3组有观察,但组21
没有)。我怎么能够
以编程方式识别部分匹配的系列,即包含一些
匹配观测的子集?这似乎是一个子序列匹配
问题,但它更抽象,因为子序列不需要是连续的。
一种方法可能是使用正则表达式,但我不能让它工作 右:
unique.strings = lapply(
apply(unique.series, 1, function(x)
which(as.logical(x))),
paste,
collapse = ","
)
reg.strings = paste0("^", lapply(
apply(unique.series, 1, function(x)
sprintf("(%d)", which(as.logical(x)))),
paste, collapse = "+(,[0-9],)*"), "$")
lapply(unique.strings, grep, x = unique.strings) # NOT CORRECT
我会很感激任何替代算法,基于正则表达式或其他算法。
答案 0 :(得分:0)
这不是一个完整的答案,但我确实得到了一半以上。我放弃了正则表达式方法而是 采用二元矩阵方法。
将在事件中表示重合观察的集合 矩阵作为TRUE值的块。我不需要那个 观察是连续的,即行的/列排序 矩阵无所谓。因此,我可以简单地重新排列我的矩阵 这些事件按块分组,然后使用块检测 或聚类算法以提取观察集。那里有两个 此过程的组件:首先,重新排列矩阵以使其成为 通过列/行交换尽可能“阻塞”。第二,确定 排列矩阵中的块。
安排部分实际上非常简单。我用了seriation
打包将矩阵重新排列成块。
set.seed(50)
d = matrix(as.logical(rbinom(50, 1, 0.75)), ncol = 10)
rownames(d) = LETTERS[1:5] # individual IDs
colnames(d) = month.abb[1:10]
library(seriation)
o = seriate(d)
d.a = permute(d, o) # rearranged matrix
我还没有为块检测确定一个好方法,但有几个SO问题涉及最大块检测(例如1,2)。我希望我能够调整这些算法来找到最大的宽度 n 或类似的东西。如果我找到一个好的解决方案,我会更新这个答案。