Выявление повторяющихся столбцов в кадре данных

Я новичок в R и пытаюсь удалить повторяющиеся столбцы из большого массива данных (строки 50K, 215 столбцов). Кадр имеет сочетание дискретных непрерывных и категориальных переменных.

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

age=18:29
height=c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5)
gender=c("M","F","M","M","F","F","M","M","F","M","F","M")
testframe = data.frame(age=age,height=height,height2=height,gender=gender,gender2=gender)

tables=apply(testframe,2,table)
dups=which(duplicated(tables))
testframe <- subset(testframe, select = -c(dups))

Это не очень эффективно, особенно для больших непрерывных переменных. Тем не менее, я пошел по этому маршруту, потому что мне не удалось получить тот же результат, используя сводку (обратите внимание: следующее предполагает оригинальный testframe содержащий дубликаты):

summaries=apply(testframe,2,summary)
dups=which(duplicated(summaries))
testframe <- subset(testframe, select = -c(dups))

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

Ответ 1

Вы можете сделать с lapply:

testframe[!duplicated(lapply(testframe, summary))]

summary суммирует распределение при игнорировании порядка.

Не 100%, но я бы использовал дайджест, если данные огромны:

library(digest)
testframe[!duplicated(lapply(testframe, digest))]

Ответ 2

Как насчет:

testframe[!duplicated(as.list(testframe))]

Ответ 3

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

duplicated(t(testframe))

Ответ 4

unique(testframe, MARGIN=2) 

не работает, хотя я думаю, что нужно, поэтому попробуйте

as.data.frame(unique(as.matrix(testframe), MARGIN=2))

или если вы беспокоитесь о том, что числа превращаются в факторы,

testframe[,colnames(unique(as.matrix(testframe), MARGIN=2))]

который производит

   age height gender
1   18   76.1      M
2   19   77.0      F
3   20   78.1      M
4   21   78.2      M
5   22   78.8      F
6   23   79.7      F
7   24   79.9      M
8   25   81.1      M
9   26   81.2      F
10  27   81.8      M
11  28   82.8      F
12  29   83.5      M

Ответ 5

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

testframe[names(testframe)[!duplicated(names(testframe))]]

Ответ 6

Вероятно, лучше сначала найти повторяющиеся имена столбцов и обработать их соответствующим образом (например, сложить два, взять среднее, первый, последний, второй, режим и т.д.). Чтобы найти повторяющиеся столбцы:

names(df)[duplicated(names(df))]

Ответ 7

Если проблема заключается в том, что кадры данных были объединены слишком много раз, например:

    testframe2 <- merge(testframe, testframe, by = c('age'))

Также хорошо удалить суффикс .x из имен столбцов. Я применил его здесь, на вершине Мостафы Резаи, отличный ответ:

    testframe2 <- testframe2[!duplicated(as.list(testframe2))]
    names(testframe2) <- gsub('.x','',names(testframe2))

Ответ 8

Как насчет просто:

unique.matrix(testframe, MARGIN=2) 

Ответ 9

На самом деле вам просто нужно будет инвертировать дублированный результат в вашем коде и придерживаться subset (что более читаемо по сравнению с записью в скобках imho)

require(dplyr)
iris %>% subset(., select=which(!duplicated(names(.))))