在R中按组查找组合模式

在R中按组查找组合模式,r,pattern-matching,combinations,R,Pattern Matching,Combinations,我有数据框,我的目标是通过ID找到组合var1的模式,如果每个组至少有3个类别相同,我们设置“是”,然后哪个ID具有相同的组合 ID1: I have 4 unique categories (A,B,C,D) ID2: I have 4 unique categories (B,C,D,F) ID3: I have 3 unique categories (A,B,C) ID4: I have 2 unique categories (A,B) ID5: I have 4 unique cat

我有数据框,我的目标是通过ID找到组合var1的模式,如果每个组至少有3个类别相同,我们设置“是”,然后哪个ID具有相同的组合

ID1: I have 4 unique categories (A,B,C,D)
ID2: I have 4 unique categories (B,C,D,F)
ID3: I have 3 unique categories (A,B,C)
ID4: I have 2 unique categories (A,B)
ID5: I have 4 unique categories (C,D,F)
我们可以看到ID1、ID2至少有3个相同的类别(B、C、D),ID1和ID3至少有(A、B、C),ID2、ID5至少有3个相同的类别(C、D、F)。所以有4个ID将有“是”,只有ID4==“否”


感谢您的进步。

问题本质上是基于公共成员身份构建邻接表,例如。为此,我们用数据(消除重复项后)制作一个表,然后取叉积

dd <- unique(df)
tab <- table(dd)
dd <- crossprod(t(tab))
diag(dd) <- 0
#    ID
# ID  1 2 3 4 5
#   1 0 3 3 2 2
#   2 3 0 2 1 3
#   3 3 2 0 2 1
#   4 2 1 2 0 0
#   5 2 3 1 0 0
因此,“1”与“2”匹配,“2”与“1”匹配,“3”与“1”匹配,“4”没有匹配,“5”与“2”匹配。通过操纵此输出以获得所需的最终产品来结束:

out <- apply(cbind(as.numeric(names(matched)), matched), MAR = 1, function(x) {
  if (any(is.na(x))) {
    data.frame(var2 = "No", var3 = x[1])
  } else {
    data.frame(var2 = "Yes", var3 = paste(sort(x), collapse = "-"))
  }
})
out <- plyr::ldply(out, .id = "ID")

merge(df, out, all.x = TRUE)
#    ID var1 var2 var3
# 1   1    A  Yes  1-2
# 2   1    B  Yes  1-2
# 3   1    C  Yes  1-2
# 4   1    A  Yes  1-2
# 5   1    D  Yes  1-2
# 6   2    D  Yes  1-2
# 7   2    C  Yes  1-2
# 8   2    D  Yes  1-2
# 9   2    B  Yes  1-2
# 10  2    F  Yes  1-2
# 11  3    A  Yes  1-3
# 12  3    B  Yes  1-3
# 13  3    C  Yes  1-3
# 14  3    C  Yes  1-3
# 15  4    A   No    4
# 16  4    B   No    4
# 17  5    D  Yes  2-5
# 18  5    D  Yes  2-5
# 19  5    C  Yes  2-5
# 20  5    C  Yes  2-5
# 21  5    F  Yes  2-5

out问题本质上是基于公共成员关系构建邻接表,例如。为此,我们用数据(消除重复项后)制作一个表,然后取叉积

dd <- unique(df)
tab <- table(dd)
dd <- crossprod(t(tab))
diag(dd) <- 0
#    ID
# ID  1 2 3 4 5
#   1 0 3 3 2 2
#   2 3 0 2 1 3
#   3 3 2 0 2 1
#   4 2 1 2 0 0
#   5 2 3 1 0 0
因此,“1”与“2”匹配,“2”与“1”匹配,“3”与“1”匹配,“4”没有匹配,“5”与“2”匹配。通过操纵此输出以获得所需的最终产品来结束:

out <- apply(cbind(as.numeric(names(matched)), matched), MAR = 1, function(x) {
  if (any(is.na(x))) {
    data.frame(var2 = "No", var3 = x[1])
  } else {
    data.frame(var2 = "Yes", var3 = paste(sort(x), collapse = "-"))
  }
})
out <- plyr::ldply(out, .id = "ID")

merge(df, out, all.x = TRUE)
#    ID var1 var2 var3
# 1   1    A  Yes  1-2
# 2   1    B  Yes  1-2
# 3   1    C  Yes  1-2
# 4   1    A  Yes  1-2
# 5   1    D  Yes  1-2
# 6   2    D  Yes  1-2
# 7   2    C  Yes  1-2
# 8   2    D  Yes  1-2
# 9   2    B  Yes  1-2
# 10  2    F  Yes  1-2
# 11  3    A  Yes  1-3
# 12  3    B  Yes  1-3
# 13  3    C  Yes  1-3
# 14  3    C  Yes  1-3
# 15  4    A   No    4
# 16  4    B   No    4
# 17  5    D  Yes  2-5
# 18  5    D  Yes  2-5
# 19  5    C  Yes  2-5
# 20  5    C  Yes  2-5
# 21  5    F  Yes  2-5

out FYI
ID2
没有类别“A”对不起,我搞砸了,让我再编辑一次我
ID2
没有类别“A”对不起,我搞砸了,让我再编辑一次谢谢你的工作,这里有一个小问题,当我稍微更改一个数据时,像ID1、ID2、ID3至少有3个相同的类别(B、C、D),它不会给我var3(1-2-3),因此它适用于成对,而不是三元组。如果您修改了问题,您可能希望打开一个新问题,仔细说明您的逻辑。例如,如果数据为1:(A,B,C,D);2:(A、B、C、D);3:(B,C,D);4:(A,B,C),结果应该是1-2吗?1-2-3? 1-2-4? 1-2-3-4?谢谢,我仍然试着用我自己的方式去做,如果我被卡住了,我将从一个新问题开始。我们有任何方法可以编码这个fastermatched=3,MAR=1,函数(x)哪个(x==TRUE)[1])匹配2=3,MAR=1,函数(x)哪个(x==TRUE)[2])匹配3,MAR 1,函数(x)哪个(x==TRUE)[3])匹配4=3,MAR 1,函数(x)哪个(x==TRUE)[4])matched5=3,MAR=1,函数(x)其中(x==TRUE)[5])rbind(matched,matched2,matched3,matched4,matched5)请打开一个新问题。在评论部分很难回答问题。感谢您的工作,这里有一个小问题,当我稍微更改一个数据时,如ID1、ID2、ID3至少有3个相同的类别(B、C、D),它不会给我var3(1-2-3),因此它适用于成对,而不是三元组。如果您修改了该问题,您可能希望打开一个新问题,仔细陈述你的逻辑。例如,如果数据为1:(A,B,C,D);2:(A、B、C、D);3:(B,C,D);4:(A,B,C),结果应该是1-2吗?1-2-3? 1-2-4? 1-2-3-4?谢谢,我仍然试着用我自己的方式去做,如果我被卡住了,我将从一个新问题开始。我们有任何方法可以编码这个fastermatched=3,MAR=1,函数(x)哪个(x==TRUE)[1])匹配2=3,MAR=1,函数(x)哪个(x==TRUE)[2])匹配3,MAR 1,函数(x)哪个(x==TRUE)[3])匹配4=3,MAR 1,函数(x)哪个(x==TRUE)[4])matched5=3,MAR=1,函数(x)其中(x==TRUE)[5])rbind(matched,matched2,matched3,matched4,matched5)请打开一个新问题。在评论部分很难回答问题。
out <- apply(cbind(as.numeric(names(matched)), matched), MAR = 1, function(x) {
  if (any(is.na(x))) {
    data.frame(var2 = "No", var3 = x[1])
  } else {
    data.frame(var2 = "Yes", var3 = paste(sort(x), collapse = "-"))
  }
})
out <- plyr::ldply(out, .id = "ID")

merge(df, out, all.x = TRUE)
#    ID var1 var2 var3
# 1   1    A  Yes  1-2
# 2   1    B  Yes  1-2
# 3   1    C  Yes  1-2
# 4   1    A  Yes  1-2
# 5   1    D  Yes  1-2
# 6   2    D  Yes  1-2
# 7   2    C  Yes  1-2
# 8   2    D  Yes  1-2
# 9   2    B  Yes  1-2
# 10  2    F  Yes  1-2
# 11  3    A  Yes  1-3
# 12  3    B  Yes  1-3
# 13  3    C  Yes  1-3
# 14  3    C  Yes  1-3
# 15  4    A   No    4
# 16  4    B   No    4
# 17  5    D  Yes  2-5
# 18  5    D  Yes  2-5
# 19  5    C  Yes  2-5
# 20  5    C  Yes  2-5
# 21  5    F  Yes  2-5