Nano Hash - криптовалюты, майнинг, программирование

Как рассчитать матрицу (совместного) вхождения из кадра данных с несколькими столбцами с помощью R?

Я новичок в R и в настоящее время работаю с данными сотрудничества в виде списка ребер с 32 столбцами и около 200 000 строк. Я хочу создать матрицу (совместного) возникновения, основанную на взаимодействии между странами. Однако я хочу подсчитать количество взаимодействий по общему количеству объекта.

Основной пример желаемого результата

Если в одной строке «Англия» встречается три раза, а «Китай» только один раз, результатом должна быть следующая матрица.

         England  China
England    3        3
China      3        1

Воспроизводимый пример

df <- data.frame(ID = c(1,2,3,4), 
 V1 = c("England", "England", "China", "England"),
 V2 = c("Greece", "England", "Greece", "England"),
V32 = c("USA", "China", "Greece", "England"))

Соответственно, пример фрейма данных в настоящее время выглядит так:

ID  V1       V2       ...   V32
1   England  Greece         USA
2   England  England        China
3   China    Greece         Greece
4   England  England        England
.
.
.

Желаемый результат

Я хочу подсчитать (совпадения) по строкам и независимо от порядка, чтобы получить матрицу (совместных) вхождений, которая учитывает низкие частоты краевых циклов (например, Англия-Англия), что приводит к следующему результату:

         China   England   Greece   USA

China    2        2         2        0

England  2        6         1        1

Greece   2        1         3        1

USA      0        1         1        1

Что было испробовано до сих пор

Я использовал igraph, чтобы получить матрицу смежности с совпадениями. Однако он вычисляет - как и предполагалось - не более двух взаимодействий одних и тех же двух объектов, в некоторых случаях оставляя мне значения намного ниже фактической частоты объектов по строке / публикации.

df <- data.frame(ID = c(1,2,3,4), 
 V1 = c("England", "England", "China", "England"),
 V2 = c("Greece", "England", "Greece", "England"),
V32 = c("USA", "China", "Greece", "England"))

# remove ID column

df[1] <- list(NULL)

# calculate co-occurrences and return as dataframe

library(igraph)
library(Matrix)

countrydf <- graph.data.frame(df)
countrydf2 <- as_adjacency_matrix(countrydf, type = "both", edges = FALSE)
countrydf3 <- as.data.frame(as.matrix(forceSymmetric(countrydf2)))

         China   England   Greece   USA

China    0        0         1        0

England  0        2         1        0

Greece   1        1         0        0

USA      0        0         0        0

Я предполагаю, что должно быть простое решение с использованием base и / или dplyr и / или table и / или reshape2, аналогичных [1], [2], [3], [4] или [5], но пока ничего не помогло, и я не смог настроить код в соответствии со своими потребностями. Я также пробовал использовать [6], однако, здесь применима та же проблема.

library(tidry)
library(dplyr)
library(stringr)


# collapse observations into one column

df2 <- df %>% unite(concat, V1:V32, sep = ",")

# calculate weights

df3 <- df2$concat %>%
  str_split(",") %>%
  lapply(function(x){
    expand.grid(x,x,x,x, w = length(x), stringsAsFactors = FALSE)
  }) %>%
  bind_rows

df4 <- apply(df3[, -5], 1, sort) %>%
  t %>%
  data.frame(stringsAsFactors = FALSE) %>%
  mutate(w = df3$w)

Я был бы рад, если бы кто-нибудь указал мне правильное направление.


  • Не могли бы вы подробнее объяснить свой входной фреймворк, для меня это не список образов. Список ребер должен состоять из 2 столбцов с идентификаторами узлов (в вашем случае - странами) и атрибутами ребер. Означает ли это, что для каждой строки вашего df вы проводите грань между всеми парами стран? 07.01.2020
  • Ваши данные больше похожи на список транзакций. См. arules пакеты для функций, которые могут помочь вам работать с вашими данными без особых дополнительных манипуляций. 07.01.2020
  • Спасибо, посмотрю! Одна строка представляет одну публикацию. Каждый столбец представляет принадлежность участвующей организации авторов к стране. Первоначально одна публикация (и связанная с ней информация) была распределена по идентификатору в несколько строк. Я суммировал одну строку по идентификатору, создал отдельные столбцы для каждой части информации (автор, страна и т. Д.), Разделив наблюдения запятой, создал разные наборы данных, содержащие идентификатор и информацию одного столбца, и преобразовал их от разделения запятой к разделению. по столбцу. 07.01.2020
  • Я хочу нарисовать границы между парами стран. Цель состоит в том, чтобы рассчитать совпадения между парами стран, отражая появление / частоту каждого объекта. Насколько я понимаю, Англия-Англия-США-Греция обычно рассматривается в матрице так, как Англия-Англия, Англия-США и т. Д. Получают вес 1, в то время как, например, США-США получат вес 0. Однако я хочу посчитать по случайности, поэтому Англия-Англия дает вес 2, а США-США - вес 1. В этом случае вес 0 был бы возможен только если две страны не отображаются вместе в одном ряду. 07.01.2020
  • В вашем базовом примере, почему вход для Китая-Англии или Англии-Китая равен 3? Не могли бы вы немного объяснить? 08.01.2020
  • Правильно ли я понимаю, что, похоже, есть два процесса, которые влияют на ваш окончательный результат; то есть недиагонали - это когда страны встречаются вместе / между ними есть грань, но диагонали - это просто необработанные подсчеты? 08.01.2020
  • @ user20650 - Да, это уже очень помогло! Спасибо! :) 08.01.2020
  • @ThomasIsCoding - Ну, основная идея - считать попарно. Я хочу выделить значение вхождения строки / наблюдения двух строк / наблюдений, которое наиболее похоже на другую строку, к которой она подключена. 08.01.2020

Ответы:


1

Могут быть более эффективные способы сделать это, но попробуйте:

library(tidyverse)

df1 <- df %>%
pivot_longer(-ID, names_to = "Category", values_to = "Country") %>%
xtabs(~ID + Country, data = ., sparse = FALSE) %>% 
crossprod(., .) 

df_diag <- df %>% 
pivot_longer(-ID, names_to = "Category", values_to = "Country") %>%
mutate(Country2 = Country) %>%
xtabs(~Country + Country2, data = ., sparse = FALSE) %>% 
diag()

diag(df1) <- df_diag 

df1

Country   China England Greece USA
  China       2       2      2   0
  England     2       6      1   1
  Greece      2       1      3   1
  USA         0       1      1   1
07.01.2020
  • Большое спасибо! Мне нужно время, чтобы понять, что делает код, но он работает нормально. 08.01.2020
  • Если я чего-то не упускаю, тот же подход за меньшее количество шагов может быть следующим: tab = table(df$ID[row(df[-1])], as.matrix(df[-1])); df1 = crossprod(tab); diag(df1) = colSums(tab); df1 08.01.2020

  • 2

    Вот способ использования пакетов dplyr и tidyr, вся идея заключается в создании фрейма данных с построчным появлением каждой страны, а затем присоединением к нему самой.

    library(dplyr)
    
    # Create dataframe sammple
    df <- data.frame(ID = c(1,2,3,4), 
                     V1 = c("England", "England", "China", "England"),
                     V2 = c("Greece", "England", "Greece", "England"),
                     V32 = c("USA", "China", "Greece", "England"),
                     stringsAsFactors = FALSE)
    
    # Get the occurance of each country in every row.
    row_occurance <- 
      df %>%
      tidyr::gather(key = "identifier", value = "country", -ID) %>%
      group_by(ID, country) %>%
      count()
    
    row_occurance %>%
      # Join row_occurance on itself to simulate the matrix
      left_join(row_occurance, by = "ID") %>%
      # Get the highest occurance row wise, this to handle when country
      # name is repeated within same row
      mutate(Occurance = pmax(n.x, n.y)) %>%
      # Group by 2 countries
      group_by(country.x, country.y) %>%
      # Sum the occurance of 2 countries together
      summarise(Occurance = sum(Occurance)) %>%
      # Spread the data to make it in matrix format
      tidyr::spread(key = "country.y", value = "Occurance", fill = 0)
    
    # # A tibble: 4 x 5
    # # Groups:   country.x [4]
    # country.x China England Greece   USA
    # <chr>     <dbl>   <dbl>  <dbl> <dbl>
    # China         2       2      2     0
    # England       2       6      1     1
    # Greece        2       1      3     1
    # USA           0       1      1     1
    
    07.01.2020
  • Большое спасибо! В частности, за пояснения. 08.01.2020

  • 3

    Вариант с использованием base::table:

    df <- data.frame(ID = c(1,2,3,4), 
        V1 = c("England", "England", "China", "England"),
        V2 = c("Greece", "England", "Greece", "England"),
        V3 = c("USA", "China", "Greece", "England"))
    
    #get paired combi and remove those from same country
    pairs <- as.data.frame(do.call(rbind, 
        by(df, df$ID, function(x) t(combn(as.character(x[-1L]), 2L)))))
    pairs <- pairs[pairs$V1!=pairs$V2, ]
    
    #repeat data frame with columns swap so that 
    #upper and lower tri have same numbers and all countries are shown
    pairs <- rbind(pairs, data.frame(V1=pairs$V2, V2=pairs$V1))
    
    #tabulate pairs
    tab <- table(pairs)
    
    #set diagonals to be the count of countries
    cnt <- c(table(unlist(df[-1L])))
    diag(tab) <- cnt[names(diag(tab))]
    
    tab
    

    выход:

             V2
    V1        China England Greece USA
      China       2       2      2   0
      England     2       6      1   1
      Greece      2       1      3   1
      USA         0       1      1   1
    
    08.01.2020
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..