Выявление повторяющихся столбцов в кадре данных
Я новичок в 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(.))))