Есть ли функция R для определения «n» совпадений в каждой строке?

Я пытаюсь агрегировать свои данные, чтобы найти корреляции/шаблоны, и хочу узнать, как и где данные могут коррелировать. В частности, я хочу определить, сколько раз идентификатор (здесь называемый «элемент») появляется вместе. Есть ли способ узнать, сколько раз каждый (id) появляется вместе подряд?

Это для более крупного data.frame, который уже был очищен и агрегирован на основе этого конкретного запроса. В прошлом я пытался применить несколько функций агрегации, суммирования и фильтрации из таких пакетов, как «data.table», «dplyr» и «tidyverse», но не смог получить то, что ищу.

В разделе 3(Показать код) я предоставил минимальный воспроизводимый пример:

set.seed(1234)
random.people<-c("Bob","Tim","Jackie","Angie","Christopher")
number=sample(12345:12350,2000,replace = T)
item=sample(random.people,2000,replace=T)

sample_data <- data.frame(cbind(number,item), stringsAsFactors = FALSE)

Используя примеры здесь, я ожидал, что вывод будет идентифицировать все комбинации, в которых имена были объединены в число, и показать n (значение) - ожидая, что результаты будут выглядеть примерно так:

Pair       value
Bob, Tim     2
Bob, Jackie  4
Bob, Angie   0

Этот вывод (то, что я надеюсь получить) скажет мне, что во всем df есть 2 раза, что Боб и Тим и 4 раза, что Боб и Джеки оба имеют одинаковый номер.

но фактический результат:

Error: Each row of output must be identified by a unique combination of keys.

Keys are shared for 2000 rows:
* 9, 23, 37, 164, 170, 180, 211...

Update: I thought of a..creative(?) solution - but hope someone can help with expedting it. I can locate all the numbers (column1) that are shared between two names using the following:

x1<-sample_data %>% dplyr::filter(item= = "Bob")
x2<-sample_data %>% dplyr::filter(item= = "Tim")
Bob<-x1[,1]
Tim<-x2[,1]
Reduce(intersect, list(Bob,Tim))

output:

[1] "12345" "12348" "12350" "12346" "12349" "12347"

Как я уже сказал, это отнимает очень много времени и потребует создания множества векторов и пересечения каждого (например, 1 вектор для каждого имени) и нескольких комбинаций.

Да, думаю, разошлись. Просто хочу: id номер, который используется совместно, и элемент (имена), которые его разделяют.

OctoCatKnows 30.05.2019 00:16

Другие ответы по вашей ссылке, вероятно, сработали бы, если бы вы добавили distinct в свой конвейер. Ваша ошибка показывает, что у нее были проблемы с распространением данных, потому что были дубликаты.

Cole 31.05.2019 12:19
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
137
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
set.seed(1234)
random.people<-c("Bob","Tim","Jackie","Angie","Christopher")
number=sample(12345:22350,2000,replace = T) # I edited ur number here.
item=sample(random.people,2000,replace=T)

sample_data <- data.frame(cbind(number,item), stringsAsFactors = FALSE)

library(tidyverse)
sample_data %>%
  # find out unique rows
  distinct() %>%
  # nest the data frame into nested tibble, so now you have
  # a "data" column, which is a list of small data frames.
  group_nest(number) %>%
  # Here we use purrr::map to modify the list column. We want each 
  # combination counts only once despite the order, so we use sort. 
  mutate(data = map_chr(data, ~paste(sort(.x$item), collapse = ", "))) %>%
  # the last two steps just count the numbers
  group_by(data) %>%
  count()

# A tibble: 21 x 2
# Groups:   data [21]
   data                         n
   <chr>                    <int>
 1 Angie                      336
 2 Angie, Bob                   8
 3 Angie, Bob, Christopher      2
 4 Angie, Bob, Jackie           1
 5 Angie, Christopher          16
 6 Angie, Jackie                9
 7 Angie, Tim                  10
 8 Bob                        331
 9 Bob, Christopher            12
10 Bob, Christopher, Jackie     1
# … with 11 more rows

Одно из возможных решений

Здравствуйте и спасибо, что помогли мне здесь. У меня проблемы с пониманием вывода. Это выглядит как df с одним obs: Не знаете, как это расшифровать:? Классы «grouped_df», «tbl_df», «tbl» и «data.frame»: 1 заб. из 2 переменных:

OctoCatKnows 29.05.2019 23:42

@ BuffsGrad16 Разве это не то, что вы ищете? Я только что изменил ваш пример и включил его в свой обновленный ответ. Вы можете проверить это.

Hao 30.05.2019 01:54

есть идеи альтернативы dplyr::group_nest? Я надеялся, что это сработает, потому что моя компания медленно загружает обновления для пакетов, а версия (dplyr), которая у нас есть, не имеет этой функции (также не удается воссоздать функцию)

OctoCatKnows 30.05.2019 13:07

@BuffsGrad16 %>% group_by(number) %>% nest() %>%

Hao 30.05.2019 16:31

Вот базовое решение R, основанное на table -> aggregate и потенциально неэффективный способ вставки имен вместе с помощью apply.

tab_data <-  data.frame(unclass(table(unique(sample_data))))
#table results in columns c(Angie.1, Bob.1, ...) - this makes it look better
names(tab_data) = sort(random.people) 

library(network)
plot.network.default(as.network(tab_data))

tab_data$n <- 1

agg_data <- aggregate(n~., data = tab_data, FUN = length)
agg_data$Pair <- apply(agg_data[, -length(agg_data)], 1, function(x) paste(names(x[x!=0]), collapse = ', '))


agg_data[order(agg_data$Pair), c('Pair', 'n') ]

                            Pair   n
1                          Angie 336
3                     Angie, Bob   8
7        Angie, Bob, Christopher   2
11            Angie, Bob, Jackie   1
5             Angie, Christopher  16
9                  Angie, Jackie   9
15                    Angie, Tim  10
2                            Bob 331
6               Bob, Christopher  12
... truncated ...

Что касается производительности, на этом относительно небольшом наборе данных оно примерно в 9 раз быстрее, чем решение dplyr:

Unit: milliseconds
           expr     min       lq     mean   median       uq      max neval
  base_solution  9.4795  9.65215 10.80984  9.87625 10.32125  46.8230   100
 dplyr_solution 78.6070 81.72155 86.47891 83.96435 86.40495 200.7784   100

Данные

set.seed(1234)
random.people<-c("Bob","Tim","Jackie","Angie","Christopher")
number=sample(12345:22350,2000,replace = T) # I edited ur number here.
item=sample(random.people,2000,replace=T)

sample_data <- data.frame(number,item, n = 1L, stringsAsFactors = FALSE)

Спасибо @Коул. Я собираюсь попробовать это позже сегодня.

OctoCatKnows 01.06.2019 16:54

Вау, мне это очень нравится - чисто. Как вы думаете, возможно ли сделать это в сетевой матрице? У меня чертовски много времени с данными, потому что они слишком большие, а сетевой график (узлы, ребра) настолько высок, что его невозможно прочитать. Я пытался применить его только к сгруппированному выводу (например, к тому, что видно в вашем agg_data), но я не могу сформировать ребра, так как вывод для узлов равен двум (Pair, N)

OctoCatKnows 02.06.2019 17:00

Вы можете задать другой вопрос, но ближе ли network::plot.network.default(network::as.network(tab_data)) к желаемому результату? Я протестировал вызов до линии tab_data$n <- 1, и у меня был сетевой график с 5 основными людьми, как и ожидалось. Однако график выглядел довольно сложным.

Cole 02.06.2019 22:36

Хм, странно - ничего не возвращается (кроме «Ошибка в plot.network.default: нет функции макета для режима fruchtermanreingold»

OctoCatKnows 03.06.2019 12:42

Я отредактировал код, чтобы добавить вызов — см. строки 5 и 6.

Cole 03.06.2019 12:54

Другие вопросы по теме