Как подсчитать, сколько раз один элемент был сгруппирован вместе с другим в R? - PullRequest
0 голосов
/ 06 июля 2018

У меня есть таблица (пример):

 Group  |  Country
-------------------
 Group1      SE
 Group1      DE  
 Group2      SE   
 Group2      DE
 Group2      FI
 Group3      SE
 Group3      FI

Я пытаюсь преобразовать его, чтобы получить:

 Country 1 | Country 2 | Count
-------------------------------
    SE          DE         2
    SE          FI         2
    FI          DE         1

Я пытался использовать счет dplyr, group_by, суммировать, но, похоже, я не могу разобраться с этим. Вместо этого я получил таблицу с каждой страной в качестве столбцов, каждой группой в виде строк и 1 или 0 в ячейке, если страна была в группе или нет.

Ответы [ 3 ]

0 голосов
/ 06 июля 2018

Вот альтернативный tidyverse подход с использованием combn

library(tidyverse)
df %>%
    group_by(Group) %>%
    summarise(cmbn = list(apply(combn(Country, 2), 2, function(x)
        paste(sort(x), collapse = "_")))) %>%
    unnest() %>%
    select(-Group) %>%
    separate(cmbn, into = c("Country 1", "Country 2"), sep = "_") %>%
    count(`Country 1`, `Country 2`)
## A tibble: 3 x 3
#  `Country 1` `Country 2`     n
#  <chr>       <chr>       <int>
#1 DE          FI              1
#2 DE          SE              2
#3 FI          SE              2

Пример данных

df <- read.table(text =
    "Group    Country
 Group1      SE
 Group1      DE
 Group2      SE
 Group2      DE
 Group2      FI
 Group3      SE
 Group3      FI", header = T, stringsAsFactors = F)
0 голосов
/ 06 июля 2018

Альтернативный dplyr подход, который применяет функцию к каждой Country комбинации значений

df = read.table(text = "
Group Country
Group1      SE
Group1      DE  
Group2      SE   
Group2      DE
Group2      FI
Group3      SE
Group3      FI
", header=T, stringsAsFactors=F)

library(dplyr)

# function that takes 2 Country values and returns the number of common groups they have
f = function(x,y) { 
  df %>% 
    filter(Country %in% c(x,y)) %>% 
    distinct() %>%
    count(Group) %>%
    filter(n > 1) %>%
    nrow() 
}

# vectorising the function
f = Vectorize(f)

# applying the function to each Country value combination
data.frame(t(combn(unique(df$Country), 2)), stringsAsFactors = F) %>%
  mutate(NumGroups = f(X1, X2))

#   X1 X2 NumGroups
# 1 SE DE         2
# 2 SE FI         2
# 3 DE FI         1
0 голосов
/ 06 июля 2018

Мы могли бы использовать base R методы, использовать table, чтобы получить частоту, сделать crossprod, установить диагональные и нижние элементы треугольника в NA и удалить строки NA после преобразования в data.frame

m1 <- crossprod(table(df1))
m1[lower.tri(m1, diag = TRUE)] <- NA
subset(as.data.frame.table(m1), !is.na(Freq))
#    Country Country.1 Freq
#4      DE        FI    1
#7      DE        SE    2
#8      FI        SE    2

Данные

df1 <- structure(list(Group = c("Group1", "Group1", "Group2", "Group2", 
"Group2", "Group3", "Group3"), Country = c("SE", "DE", "SE", 
"DE", "FI", "SE", "FI")), .Names = c("Group", "Country"),
 class = "data.frame", row.names = c(NA, -7L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...