与r中缺失或不匹配的组合

时间:2012-10-06 13:00:22

标签: r dataframe permutation combinations

我必须创造独特的组合,同时允许一些不匹配。以下是一个例子:

set.seed (1234)
dataf <- data.frame (var1 = sample( c("A", "B", "-"),20, replace = T),
            var2 = sample( c("A"),20, replace = T),
            var3 = sample( c("B", "B", "B", "-"),20, replace = T),
            var4 = sample( c("A","A", "A",  "-"),20, replace = T),
            var5 = sample( c("A", "B", "A", "A", "-"),20, replace = T)
            )
 dataf

规则:

(1)生成独特的组合:

     A B     A  B  B   - combination 1
    A  A     A  B  B    - combination 2
    B  B     B  A  A    - combination 3 
   so on ...

(2)允许一个(可以是n)不匹配来创建一个类别。例如:

A   B    A  B  B
A   A    A  B  B
B   A    A  B  B
B   A    B  B  B 
B   A    A  B  A

与不同变量的单一不匹配相同。

(3)“ - ”表示缺失值,可以视为与匹配中的整数类似的方式,即允许一个不匹配。

A   B    A  B  B
 A   -    A  B  B
 A   B    A  -  B

但是,如果有两个缺失值,则组合声明为未知( - )

 A   B    A  B  B
 A   -    A  -  B
 A   B    A  -  -

以下是针对上述数据的锻炼。

    var1 var2 var3 var4 var5       comb
1     A    A    B    -    -       -

2     B    A    B    A    A        1
3     B    A    B    A    A        1
4     B    A    B    A    A        1
5     -    A    B    A    A        1
6     B    A    B    A    -        1

7     A    A    B    A    B        2
8     A    A    B    A    B        2

9     B    A    B    A    A        1

10    B    A    -    A    -        -

11    -    A    B    A    A        1

12    B    A    B    -    -        -

13    A    A    B    A    A        2

14    -    A    B    -    A        -

15    A    A    B    A    A        2
16    -    A    B    A    A        2
17    A    A    B    A    B        2

18    A    A    -    A    A        3

19    A    A    B    A    B        2

20    A    A    -    A    A        3

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我将如何做到这一点。这个想法是创建一个距离矩阵,因此您可以将数据聚类成行间距为零的行组。

首先,让我们删除(暂时)具有两个或更多短划线的行:

two.dashes <- apply(dataf, 1, function(x)sum(x == '-') >= 2)
subdata <- dataf[!two.dashes,]

然后,让我们计算一个距离矩阵。

mydist.fun <- function(i, j, x = subdata) {
   row.i <- x[i, ]
   row.j <- x[j, ]
   idx   <- row.i != '-' & row.j != '-'
   sum(row.i[idx] != row.j[idx])
}
rows.idx  <- seq_len(nrow(subdata))
rows.dist <- as.dist(outer(rows.idx, rows.idx, Vectorize(mydist.fun)))

然后,让我们使用群集来分组您的数据。我正在使用一个完整的层次聚类并在height = 0切割它,即它创建了一组点,其中所有点的距离都为零。

hc <- hclust(rows.dist)
members <- cutree(hc, h = 0)

让我们把所有东西放在一起:

comb <- rep('-', nrow(dataf))
comb[!two.dashes] <- members
dataf$comb <- comb
dataf
#    var1 var2 var3 var4 var5 comb
# 1     A    A    B    -    -    -
# 2     B    A    B    A    A    1
# 3     B    A    B    A    A    1
# 4     B    A    B    A    A    1
# 5     -    A    B    A    A    1
# 6     B    A    B    A    -    1
# 7     A    A    B    A    B    2
# 8     A    A    B    A    B    2
# 9     B    A    B    A    A    1
# 10    B    A    -    A    -    -
# 11    -    A    B    A    A    1
# 12    B    A    B    -    -    -
# 13    A    A    B    A    A    3
# 14    -    A    B    -    A    -
# 15    A    A    B    A    A    3
# 16    -    A    B    A    A    1
# 17    A    A    B    A    B    2
# 18    A    A    -    A    A    3
# 19    A    A    B    A    B    2
# 20    A    A    -    A    A    3

这暴露了您预期输出中的矛盾。例如,第7行和第13行不应属于同一组。此外,还有一些带有单个短划线的行可以转到不同的组,例如第16行。