Как удалить строки, содержащие повторяющиеся символы в R - PullRequest
1 голос
/ 03 мая 2020

Я хочу удалить всю строку, если в двух столбцах есть дубликаты. Любая быстрая помощь в этом в R (для очень большого набора данных) будет высоко оценена. Например:

mydf <- data.frame(p1=c('a','a','a','b','g','b','c','c','d'),
                               p2=c('b','c','d','c','d','e','d','e','e'),
                               value=c(10,20,10,11,12,13,14,15,16))

Это дает:

mydf

 p1 p2 value
1  a  b    10
2  c  c    20
3  a  d    10
4  b  c    11
5  d  d    12
6  b  b    13
7  c  d    14
8  c  e    15
9  e  e    16

Я хочу получить:

p1 p2 value
1  a  b    10
2  a  d    10
3  b  c    11
4  c  d    14
5  c  e    15

Ответы [ 3 ]

2 голосов
/ 03 мая 2020

ваша заметка в комментариях предполагает, что ваша реальная проблема более сложна. Есть некоторая предварительная обработка, которую вы можете выполнить со своими строками, прежде чем сравнивать p1 с p2. Вы будете иметь опыт работы с доменом, чтобы знать, какие шаги уместны, но вот первое начало. Я удаляю все интервалы и знаки препинания из p1 и p2. Затем я проверяю их все в верхнем регистре, прежде чем проверять на равенство. Вы можете изменить функцию clean_str, включив в нее дополнительные / различные операции очистки.

Кроме того, вы можете рассмотреть примерное соответствие для опечаток адресов / разговорных соглашений об именах. Пакет stringdist - хорошее место для старта.

mydf <- data.frame(p1=c('New York','New York','New York','TokYo','LosAngeles','MEMPHIS','memphis','ChIcAGo','Cleveland'),
                   p2=c('new York','New.York','MEMPHIS','Chicago','knoxville','tokyo','LosAngeles','Chicago','CLEVELAND'),
                   value=c(10,20,10,11,12,13,14,15,16),
                   stringsAsFactors = FALSE)


mydf[mydf$p1 != mydf$p2,]
#>           p1         p2 value
#> 1   New York   new York    10
#> 2   New York   New.York    20
#> 3   New York    MEMPHIS    10
#> 4      TokYo    Chicago    11
#> 5 LosAngeles  knoxville    12
#> 6    MEMPHIS      tokyo    13
#> 7    memphis LosAngeles    14
#> 8    ChIcAGo    Chicago    15
#> 9  Cleveland  CLEVELAND    16

clean_str <- function(col){
  #removes all punctuation
  d <- gsub("[[:punct:][:blank:]]+", "", col)
  d <- toupper(d)
  return(d)
}

mydf$p1 <- clean_str(mydf$p1)
mydf$p2 <- clean_str(mydf$p2)

mydf[mydf$p1 != mydf$p2,]
#>           p1         p2 value
#> 3    NEWYORK    MEMPHIS    10
#> 4      TOKYO    CHICAGO    11
#> 5 LOSANGELES  KNOXVILLE    12
#> 6    MEMPHIS      TOKYO    13
#> 7    MEMPHIS LOSANGELES    14

Создан в 2020-05-03 пакетом Представления (v0.3.0)

2 голосов
/ 03 мая 2020

Несколько способов сделать это. Среди них:

База R

mydf[mydf$p1 != mydf$p2, ]

dplyr

library(dplyr)
mydf %>% filter(p1 != p2)

data.table

library(data.table)
setDT(mydf)
mydf[p1 != p2]
1 голос
/ 03 мая 2020

Вот двухэтапное решение, основанное на данных @ Chase:

Первый шаг (как предложено @Chase) - предварительно обработайте ваши данные в p1 и p2, чтобы сделать их сопоставимыми:

# set to lower-case:
mydf[,c("p1", "p2")] <- lapply(mydf[,c("p1", "p2")], tolower)
# remove anything that's not alphanumeric between words:
mydf[,c("p1", "p2")] <- lapply(mydf[,c("p1", "p2")], function(x) gsub("(\\w+)\\W(\\w+)", "\\1\\2", x))

Второй шаг - (i) использование apply, paste строк вместе, (ii) использование grepl и обратная ссылка \\1 для поиска соседних дубликатов в этих строках и (iii) ) удалить (-) эти строки which содержат следующие дубликаты:

mydf[-which(grepl("\\b(\\w+)\\s+\\1\\b", apply(mydf, 1, paste0, collapse = " "))),]
          p1         p2 value
3    newyork    memphis    10
4      tokyo    chicago    11
5 losangeles  knoxville    12
6    memphis      tokyo    13
7    memphis losangeles    14
...