Создайте ключ группы в двух столбцах - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь решить приведенную ниже проблему, но мне трудно ее объяснить. Я хочу назначить добавочное значение на основе связи между двумя столбцами (цвета и буквы).

Colours <- c("Green","Red","Green","Green","Blue","Red","Brown")
Letters <- c("X","C","Y","A","C","T","P")
df <- data.frame(Colours,Letters)
df

    Colours Letters
1   Green       X
2     Red       C
3   Green       Y
4   Green       A
5    Blue       C
6     Red       T
7   Brown       P

Я назначу значение для группы, чтобы все идентичные цвета находились в одной группе вместе с любым другим цветом, имеющим одинаковые буквы. Например, группа 2 включает Red & Blue с учетом общей связи с буквой C.

Group <- c(1,2,1,1,2,2,3)
df <- data.frame(df,Group)
df
    Colours Letters Group
1   Green       X     1
2     Red       C     2
3   Green       Y     1
4   Green       A     1
5    Blue       C     2
6     Red       T     2
7   Brown       P     3

Если добавить дополнительную строку с Color = Green и Letter = C, столбец Group изменится на приведенный ниже. Все зеленые будут сгруппированы вместе с любым другим цветом (например, красным), имеющим одинаковую букву (C в случае красного). Кроме того, любой цвет, который разделил букву с красным, также будет добавлен в ту же группу, что и зеленый (как в случае с синим, который разделяет букву С с красным).

  Colours Letters Group
1   Green       X     1
2     Red       C     1
3   Green       Y     1
4   Green       A     1
5    Blue       C     1
6     Red       T     1
7   Brown       P     2
8   Green       C     1

Может кто-нибудь помочь?

1 Ответ

0 голосов
/ 07 ноября 2018

Как отмечал выше @Frank, вы описываете проблему с графиком в том, что вы хотите, чтобы метка вашей группы отображала связанные компоненты - цвета, которые разделяют букву. Преобразовав ваши столбцы в графический объект, вы можете выяснить, что такое отдельные компоненты, и вернуть их в виде групп:

Colours <- c("Green","Red","Green","Green","Blue","Red","Brown")
Letters <- c("X","C","Y","A","C","T","P")
df <- data.frame(Colours,Letters)

Group <- c(1,2,1,1,2,2,3)
df <- data.frame(df,Group)

# load the igraph package for working with graphs
library(igraph)
adj.mat <- table(df$Colours, df$Letters) %*% t(table(df$Colours, df$Letters))

# visual inspection makes it clear what the components are
g <- graph_from_adjacency_matrix(adj.mat, mode = 'undirected', diag = F)
plot(g)

# we create a dataframe that matches each color to a component
mdf <- data.frame(Group_test = components(g)$membership,
                  Colours = names(components(g)$membership))

mdf
#>       Group_test Colours
#> Blue           1    Blue
#> Brown          2   Brown
#> Green          3   Green
#> Red            1     Red

# Then we just match them together
dplyr::left_join(df, mdf)
#> Joining, by = "Colours"
#>   Colours Letters Group Group_test
#> 1   Green       X     1          3
#> 2     Red       C     2          1
#> 3   Green       Y     1          3
#> 4   Green       A     1          3
#> 5    Blue       C     2          1
#> 6     Red       T     2          1
#> 7   Brown       P     3          2

Очевидно, что группы имеют разную нумерацию, но цвета разделяются одинаково.

Мы можем рассматривать расширенный случай как проверку работоспособности, где мы добавляем цвет связывания, который уменьшает набор компонентов до 2:

# examining the extended case as a check
df2 <- data.frame(Colours = c(Colours, "Green"), Letters = c(Letters, "C"))
df2
#>   Colours Letters
#> 1   Green       X
#> 2     Red       C
#> 3   Green       Y
#> 4   Green       A
#> 5    Blue       C
#> 6     Red       T
#> 7   Brown       P
#> 8   Green       C

# lets wrap the procedure in a function for convenience
getGroup <- function(col, let, plot = FALSE){
  adj.mat <- table(col, let) %*% table(let, col)
  g <- graph_from_adjacency_matrix(adj.mat, mode = 'undirected',
                                   diag = F)
  if (plot) {plot(g)}
  comps <- components(g)$membership
  mdf <- data.frame(Group = comps, Colours = names(comps))
  mdf
}

# we get our desired group key (which we can merge back to the dataframe)
getGroup(df2$Colours, df2$Letters)
#>       Group Colours
#> Blue      1    Blue
#> Brown     2   Brown
#> Green     1   Green
#> Red       1     Red

Создано в 2018-11-07 пакетом представ. (v0.2.1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...