Подмножество списков в R, чтобы получить самый длинный список

У меня есть список элементов с разным количеством элементов, многие из которых являются подмножествами друг друга. Я хотел бы удалить все элементы, полный набор элементов которых существует в других элементах.

Так, например, для:


listy<-list("item1"=c(10,210,300,400,500,600), "item2"=c(10,210,300), "item3"=c(500,600), "item4"=c(210, 300), "item5"=c(700,800,900))

Пункты 2,3 и 4 являются подмножествами пункта 1, поэтому мой желаемый результат:

listy2<-c("item1"=c(10,210,300,400,500,600), "item5"=c(700,800,900))

До сих пор я пытался преобразовать его в тиббл, сортировать по первому столбцу, а затем удалять дубликаты первого столбца. Но это очень неэффективно и удаляет только те, которым соответствует первый столбец, а не те, где совпадают последующие (например, item3 и item4 по сравнению с item1 здесь). Или я мог бы сделать цикл для всех против всех grepl, создавая строки поиска для каждого элемента в списке. Пример: что-то вроде этого, но на самом деле это не работает из-за строки поиска:

for(ity in 1:length(listy)){
    if (grepl(paste(unlist(listy[[ity]]), sep = "|"), listy[[c(1:3)[-ity]]])){ 
print(ity)
}}

Но опять же, это было бы очень неэффективно (а мои фактические списки содержат 100 000 элементов или более, каждый из которых содержит до 20 000 элементов). Я уверен, что мне не хватает какой-то очень простой функции, и любая помощь будет принята с благодарностью.

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
idx <- sapply(seq_along(listy), \(i) any(sapply(listy[-i], \(j) all(listy[[i]] %in% j))))
listy[!idx]
# $item1
# [1]  10 210 300 400 500 600 500
# 
# $item5
# [1] 700 800 900

Как это работает

По сути, это двойной цикл. Первый sapply перебирает индекс (i) всех элементов в вашем списке. Второй sapply перебирает все элементы вашего списка, кроме i, и сравнивает их. Вам необходимо удалить этот индекс, иначе совпадение всегда будет.

Вот версия происходящего, чтобы помочь вам визуализировать:

for (i in seq_along(listy)) {
  for (j in listy[-i]) {
    lgl <- all(list[[i]] %in% j)
    cat("All c(", toString(listy[[i]]), ") in c(", toString(j), ")? --> ", lgl, "\n", sep = "")
  }
}

Потрясающий! Спасибо! Можно ли объяснить, как это работает? Я никогда раньше не видел () в этом контексте.

gpo 02.08.2024 19:55

@gpo Конечно! Я добавил раздел, чтобы помочь вам понять, надеюсь, это имеет смысл. Я не уверен, что вы имеете в виду под словами «Я никогда раньше не видел () в этом контексте». Вы имеете в виду \(i)?

LMc 02.08.2024 20:16

Вот igraph вариант

library(igraph)
outer(listy, listy, Vectorize(\(x, y) all(y %in% x))) %>%
  graph_from_adjacency_matrix(diag = FALSE) %>%
  degree(mode = "in") %>%
  subset(. == 0) %>%
  names() %>%
  `[`(listy, .)

который дает

$item1
[1]  10 210 300 400 500 600

$item5
[1] 700 800 900

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