Удалить повторяющиеся строки в R, хотя в другом порядке - PullRequest
0 голосов
/ 10 января 2019

Такое ощущение, что это должно быть очевидно, но я действительно этого не вижу!

Вот небольшой пример того типа данных, с которыми я имею дело:

x1 <- as.character(c("Apple", "Banana", "Cat", "Dog", "Orange"))
x2 <- as.character(c("Banana", "Orange", "Dog", "Cat", "Apple"))
x3 <- as.character(c("Orange", "Apple", NA, NA, "Banana"))         
groups <- data_frame(x1, x2, x3)

Фрейм данных имеет пять рядов, но в действительности только два уникальны - один из них содержит три плода, а другой содержит двух животных при чтении через ряд. Причина в том, что есть пять рядов, состоит в том, что для каждого фрукта или животного есть ряд, указывающий других членов их группы.

Я либо хочу удалить дублирующиеся строки (мне все равно, какие из них удаляются, если в каждой группе осталась только одна строка), либо я могу выбрать имя группы в новом столбце, поэтому пять строк, но с дополнительным столбцом, который выглядит примерно так: "Fruit", "Fruit", "Animal", "Animal", "Fruit. Что касается второго варианта, мне все равно, какие имена групп, если они идентифицируют различные категории.

Я исследовал, используя duplicated (что-то вроде groups[!duplicated(groups$x1), ]), но очевидно, что это не работает, потому что в каком-либо отдельном столбце нет дубликатов - речь идет о том, есть ли что-то в этой строке. Возможно, что-то может быть связано с упорядочением строк в алфавитном порядке, но я не уверен, что это выполнимо - я ничего не могу найти на нем (и не могу понять, как это обычно было бы особенно полезно ...).

Мои реальные данные содержат сотни строк, поэтому ручная идентификация групп не очень привлекательна!

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Вы можете использовать duplicated после разумной перестройки данных. Одним разумным способом было бы иметь значения TRUE/FALSE для каждого фрукта и животного: вместо x1, имеющего значение "dog", можно было бы иметь dog, имеющее значение TRUE. Это можно сделать, например, так:

g <- na.omit(unique(unlist(groups)))
df <- t(apply(as.matrix(groups), 1, function(x) g %in% x))
# if needed, you could make the `df` human-readable:
df <- setNames(as.data.frame(df), g)
duplicated(df)

Данные

x1 <- as.character(c("Apple", "Banana", "Cat", "Dog", "Orange"))
x2 <- as.character(c("Banana", "Orange", "Dog", "Cat", "Apple"))
x3 <- as.character(c("Orange", "Apple", NA, NA, "Banana"))         
groups <- data.frame(x1, x2, x3, stringsAsFactors=FALSE)
0 голосов
/ 10 января 2019

Я не знаю, дает ли ваш пример данных именно тот пример, по которому вы хотите получить помощь, но здесь есть взлом. Как уже упоминалось другими в комментариях, большинство инструментов просматривают уникальные пары в строках. Если сопряжение не имеет значения, вы можете сделать что-то вроде:

    library(dplyr)

    x1 <- as.character(c("Apple", "Banana", "Cat", "Dog", "Orange"))
    x2 <- as.character(c("Banana", "Orange", "Dog", "Cat", "Apple"))
    x3 <- as.character(c("Orange", "Apple", NA, NA, "Banana"))         
    groups <- data_frame(x1, x2, x3)

    groups %>% 
       mutate_all(sort, na.last = TRUE) %>% 
       unique()

Независимо от того, уникальная функция будет смотреть на уникальные пары в строках, если порядок их появления в ваших данных имеет значение. Определенно медленно, хотя, и я уверен, что есть что-то быстрее. Как что-то из SQL с SELECT DISTINCT *.

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