根据多列

时间:2017-03-07 16:54:43

标签: r subset cluster-analysis similarity balance

我正在寻找查找行子集的可能性(一个子集应包含6行),其中多列的值 - 均值最相似。因此,我希望R搜索我的data.frame并创建每行6行的子集,以便最终这些子集彼此最相似。相似度可以测量为欧几里德距离(正如@David Robinson所指出的那样)。

我的数据如下:

  TID   Cue1  Cue2  Cue3
  1    2.06   1.90  3.82
  2    5.18   4.13  5.10
  3    5.09   2.85  2.80
  4    1.93   4.14  4.75
  ...   ...    ...   ...       

我现在想知道R中是否有方法,我发现以下内容:

-give me eg每个包含6行的4个子集,其中4个子集在 1中具有最可能的同类,Cue2和Cue3 表示(SD不重要),而每个子集包含唯一的行(子集之间没有重复的行)

一个例子是(与我的示例中的数据不匹配):

- 子集1包含 TID 1,TID 6,TID 14,TID 28,TID 39,TID 50,此子集具有cue-means(Cue1 = 3,2; Cue2 = 2, 5; Cue3 = 4)

- 子集2包含 TID 3,TID 12,TID 20,TID 40,TID 54,TID 59,此子集具有提示均值(Cue1 = 3,3; Cue2 = 2, 6; Cue3 = 4,1)。

这样两个子集在提示方式上非常(大多数)相似。 R现在应该给我命名形成子集的rownumbers(或TID值)。

在R中有没有可能做到这一点?

以下是我的数据的可重现示例:

    mysamp <- function(n, m, s, lwr, upr, nnorm) {
  set.seed(1)
  samp <- rnorm(nnorm, m, s)
  samp <- samp[samp >= lwr & samp <= upr]
  if (length(samp) >= n) {
    return(sample(samp, n))
  }  
 } 
Cue1 <- mysamp(n=60, m=3, s=1.5, lwr=1, upr=6, nnorm=1000)
Cue2 <- mysamp(n=60, m=3, s=2.5, lwr=1, upr=6, nnorm=1000)
Cue3 <- mysamp(n=60, m=4, s=1.5, lwr=1, upr=6, nnorm=1000)

df <- data.frame(TID= 1:60, Cue1= Cue1, Cue2= Cue2, Cue3= Cue3)

1 个答案:

答案 0 :(得分:0)

这是一个群集问题,因此您希望通过以下方式处理它:

  • 计算距离矩阵
  • 使用它构建一个&#34树&#34;相似的节点组
  • 提取树大小最低的子群集

距离矩阵和层次聚类可以完成:

distances <- dist(df[, -1])
h <- hclust(distances)

有很多方法可以在算法上拉出树上的低簇;因为我习惯使用dplyr / purrr / tidyr,所以我会展示一个解决方案。这需要使用cutree在每个可能的级别将树分开,然后找到每组六个第一次出现。

library(dplyr)
library(tidyr)
library(purrr)

clusterings <- data_frame(ncluster = seq(nrow(df), 1)) %>%
  unnest(membership = map(ncluster, ~ cutree(h, .))) %>%
  group_by(ncluster) %>%
  mutate(row = row_number()) %>%
  ungroup() %>%
  nest(-ncluster, -membership) %>%
  mutate(size = map_dbl(data, nrow)) %>%
  filter(size == 6) %>%
  distinct(membership, .keep_all = TRUE) %>%
  unnest(data) %>%
  mutate(TID = df$TID[row])

在您的数据上,返回:

# A tibble: 42 × 5
   ncluster membership  size   row   TID
      <int>      <int> <dbl> <int> <int>
1        29          9     6     9     9
2        29          9     6    30    30
3        29          9     6    39    39
4        29          9     6    41    41
5        29          9     6    43    43
6        29          9     6    57    57
7        21         13     6    15    15
8        21         13     6    20    20
9        21         13     6    25    25
10       21         13     6    29    29
# ... with 32 more rows

因此,(9,30,39,41,43,57)组成你的第一组6,而第二组开始于(15,20,25,29 ......)