Как удалить дублированные строки и столбцы из фрейма данных, не учитывая NA? - PullRequest
0 голосов
/ 08 февраля 2019

Я хотел бы удалить дублированные столбцы из фрейма данных, не учитывая NA.Все столбцы фрейма данных являются числовыми векторами одинаковой длины.Вот пример:

> df <- data.frame(a = c(1,2,NA,4,4), b= c(5,6,7,8,8), c= c(5,6,7,8,8), d = c(9,8,7,6,NA), e = c(NA,8,7,6,6))
> df
   a b c  d  e
1  1 5 5  9 NA
2  2 6 6  8  8
3 NA 7 7  7  7
4  4 8 8  6  6
5  4 8 8 NA  6

Я хотел бы получить этот фрейм данных в результате:

> df_clear
   a b d
1  1 5 9
2  2 6 8
3 NA 7 7
4  4 8 6

Я попробовал «уникальный», но безуспешно. Только дублирует безNA были удалены.

> df_clear <- 
+   df %>%
+     unique %>%
+     t %>%
+     as.matrix %>%
+     unique %>%
+     t %>%
+     as.data.frame
> df_clear
   a b  d  e
1  1 5  9 NA
2  2 6  8  8
3 NA 7  7  7
4  4 8  6  6
5  4 8 NA  6

«отличное» от dplyr тоже не помогло. Я даже потерял имена столбцов при таком подходе, что является проблемой.

> df_clear <- 
+   df %>%
+     distinct %>%
+     t %>%
+     as.data.frame %>%
+     distinct %>%
+     t %>%
+     as.data.frame
> df_clear
   V1 V2 V3 V4
V1  1  5  9 NA
V2  2  6  8  8
V3 NA  7  7  7
V4  4  8  6  6
V5  4  8 NA  6

Интересно,есть любая функция, которая выполняет эту работу, или я должен написать ее для себя. Реальный фрейм данных содержит более 1000 строк и столбцов.

Большое спасибо за вашу помощь!

РЕДАКТИРОВАТЬ

После прочтения комментариев я понял, что недостаточно определил исходный вопрос. Вот некоторые пояснения. Для простоты я сосредоточусь только на строках:
- В случае дубликатов оставшаяся строка должна содержать как можно меньше NA.по возможности. Например, df1 должен выглядеть как df1_clear

> df1
   a b  d e
1  1 4  7 1
2  3 6 NA 3
3  2 5  8 2
4 NA 6  9 3
> df1_clear
  a b d e
1 1 4 7 1
2 2 5 8 2
3 3 6 9 3
  • Дубликаты не обязательно являются последовательными.
  • Может быть более одного NA в ряду.

1 Ответ

0 голосов
/ 08 февраля 2019

Следующее немного сложнее, но оно выполняет свою работу.
Вызывает функцию в пределах fun дважды, чтобы удалить дубликаты исходного кадра данных, а затем его транспонирования.

fun <- function(DF){
  f <- function(DF1){
    df1 <- DF1
    df1[] <- lapply(df1, function(x){
      y <- zoo::na.locf(x)
      if(length(y) < length(x)) y <- zoo::na.locf(x, fromLast = TRUE)
      y
    })
    DF1[!duplicated(df1), ]
  }
  df2 <- f(DF)
  df2 <- as.data.frame(t(df2))
  df2 <- t(f(df2))
  as.data.frame(df2)
}

fun(df)
#   a b d
#1  1 5 9
#2  2 6 8
#3 NA 7 7
#4  4 8 6

Исходя из вышеизложенного, это можно сделать с помощью функции f() в трубах fun и dplyr.Функция f() ниже является просто копией и вставкой функции выше.

library(dplyr)


f <- function(DF1){
  df1 <- DF1
  df1[] <- lapply(df1, function(x){
    y <- zoo::na.locf(x)
    if(length(y) < length(x)) y <- zoo::na.locf(x, fromLast = TRUE)
    y
  })
  DF1[!duplicated(df1), ]
}


df %>%
  f() %>% t() %>% as.data.frame() %>%
  f() %>% t() %>% as.data.frame()

#   a b d
#1  1 5 9
#2  2 6 8
#3 NA 7 7
#4  4 8 6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...