3

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

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

任何的想法 ?

4

1 回答 1

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 行。

于 2012-10-06T17:26:28.803 回答