Удалить (квази) одинаковые строки - PullRequest
1 голос
/ 26 марта 2019

в следующем файле data.df мы видим, что строки 2 и 3 идентичны и отличается только среднее значение строки 4.

    iso3 dest   code year          uv       mean
1    ALB  AUT 490700 2002  14027.2433 427387.640
2    ALB  BGR 490700 2002   1215.5613  11886.494
3    ALB  BGR 490700 2002   1215.5613  11886.494
4    ALB  BGR 490700 2002   1215.5613  58069.405
5    ALB  BGR 843050 2002    677.9827   4272.176
6    ALB  BGR 851030 2002  31004.0946  32364.379
7    ALB  HRV 392329 2002   1410.0072   6970.930

Есть ли простой способ автоматически найти эти строки? Я нашел эту тему , которая, кажется, отвечает на этот вопрос, но я не понимаю, как 'duplicated () `работает ...

Мне нужна «простая» команда, в которой я мог бы указать, какое значение столбца по строке должно быть одинаковым. что-то вроде: function(data.df, c(iso3, dest, code, year, uv, mean)) чтобы найти те же самые строки и function(data.df, c(iso3, dest, code, year, uv)) чтобы найти "квази" те же строки ...

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

2    ALB  BGR 490700 2002   1215.5613  11886.494
3    ALB  BGR 490700 2002   1215.5613  11886.494

и во втором:

2    ALB  BGR 490700 2002   1215.5613  11886.494
3    ALB  BGR 490700 2002   1215.5613  11886.494
4    ALB  BGR 490700 2002   1215.5613  58069.405

есть идеи?

Ответы [ 4 ]

3 голосов
/ 26 марта 2019

Мы могли бы написать функцию и затем передать столбцы, которые мы хотим рассмотреть.

get_duplicated_rows <- function(df, cols) {
  df[duplicated(df[cols]) | duplicated(df[cols], fromLast = TRUE), ]
}

get_duplicated_rows(df, c("iso3", "dest", "code", "year", "uv","mean"))

# iso3 dest   code year     uv  mean
#2  ALB  BGR 490700 2002 1215.6 11886
#3  ALB  BGR 490700 2002 1215.6 11886

get_duplicated_rows(df, c("iso3", "dest", "code", "year", "uv"))
#  iso3 dest   code year     uv  mean
#2  ALB  BGR 490700 2002 1215.6 11886
#3  ALB  BGR 490700 2002 1215.6 11886
#4  ALB  BGR 490700 2002 1215.6 58069
1 голос
/ 26 марта 2019

Мы можем использовать group_by_all и фильтровать с более чем 1 частотным отсчетом

library(dplyr)
df1 %>%
   group_by_all() %>% 
   filter(n() > 1)
# A tibble: 2 x 6
# Groups:   iso3, dest, code, year, uv, mean [1]
#  iso3  dest    code  year    uv   mean
#  <chr> <chr>  <int> <int> <dbl>  <dbl>
#1 ALB   BGR   490700  2002 1216. 11886.
#2 ALB   BGR   490700  2002 1216. 11886.

, если это подмножество столбцов, использовать group_by_at

df1 %>%
     group_by_at(vars(iso3, dest, code, year, uv)) %>%
     filter(n() > 1)
# A tibble: 3 x 6
# Groups:   iso3, dest, code, year, uv [1]
#  iso3  dest    code  year    uv   mean
#  <chr> <chr>  <int> <int> <dbl>  <dbl>
#1 ALB   BGR   490700  2002 1216. 11886.
#2 ALB   BGR   490700  2002 1216. 11886.
#3 ALB   BGR   490700  2002 1216. 58069.
1 голос
/ 26 марта 2019

Используя пакеты dplyr и rlang, мы можем достичь этого -

Раствор-

find_dupes <- function(df,cols){
  df <- df %>% get_dupes(!!!rlang::syms(cols))
  return(df)
}

выход

1-й случай -

> cols
[1] "iso3" "dest" "code" "year" "uv" 

> find_dupes(df, cols)

# A tibble: 3 x 7
  iso3  dest    code  year    uv dupe_count   mean
  <fct> <fct>  <int> <int> <dbl>      <int>  <dbl>
1 ALB   BGR   490700  2002 1216.          3 11886.
2 ALB   BGR   490700  2002 1216.          3 11886.
3 ALB   BGR   490700  2002 1216.          3 58069.

2-й случай-

> cols
[1] "iso3" "dest" "code" "year" "uv"   "mean"

> find_dupes(df,cols)

# A tibble: 2 x 7
  iso3  dest    code  year    uv   mean dupe_count
  <fct> <fct>  <int> <int> <dbl>  <dbl>      <int>
1 ALB   BGR   490700  2002 1216. 11886.          2
2 ALB   BGR   490700  2002 1216. 11886.          2

Примечание-

rlan::syms функция принимает строки в качестве входных данных и превращает их в символы. В отличие от as.name (), они заранее конвертируют строки в собственную кодировку. Это необходимо, поскольку символы автоматически удаляют метку кодирования строк.

Чтобы передать список имен векторов в функции dplyr, мы используем syms.

!!! используется для кавычек

1 голос
/ 26 марта 2019

Вы можете получить квази-дупликации, если вы посмотрите на каждую функцию по очереди, а затем рассмотрите строки с Rowsum, превышающей целевое значение.

toread <- "    iso3 dest   code year          uv       mean
    ALB  AUT 490700 2002  14027.2433 427387.640
    ALB  BGR 490700 2002   1215.5613  11886.494
    ALB  BGR 490700 2002   1215.5613  11886.494
    ALB  BGR 490700 2002   1215.5613  58069.405
    ALB  BGR 843050 2002    677.9827   4272.176
    ALB  BGR 851030 2002  31004.0946  32364.379
    ALB  HRV 392329 2002   1410.0072   6970.930"

df <- read.table(textConnection(toread), header = TRUE) 
closeAllConnections()

get_quasi_duplicated_rows <- function(df, cols, cut){
  result <- matrix(nrow = nrow(df), ncol = length(cols))
  colnames(result) <- cols
  for(col in cols){
    dup <- duplicated(df[col]) | duplicated(df[col], fromLast = TRUE)
    result[ , col] <- dup
  }
  return(df[which(rowSums(result) > cut), ])
}

get_quasi_duplicated_rows(df, c("iso3", "dest", "code", "year", "uv","mean"), 4)


 iso3 dest   code year       uv     mean
2  ALB  BGR 490700 2002 1215.561 11886.49
3  ALB  BGR 490700 2002 1215.561 11886.49
4  ALB  BGR 490700 2002 1215.561 58069.40
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...