Как удалить дублированные значения в столбцах таблицы data.table? - PullRequest
0 голосов
/ 17 января 2020

Я хочу удалить дублированные значения в каждом столбце неравномерной таблицы данных. Например, если исходные данные (реальная таблица данных содержит много строк и столбцов):

dt <- data.table(A = c("5p", "3p", "3p", "6y", NA), B = c("1c", "4r", "1c", NA, NA), C = c("4f", "5", "5", "5", "4m"))
> dt
      A    B  C
1:   5p   1c 4f
2:   3p   4r  5
3:   3p   1c  5
4:   6y <NA>  5
5: <NA> <NA> 4m

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

A    B    C
5p   1c   4f
3p   4r   5
NA   NA   NA
6y   NA   NA
NA   NA   4m

Я пытаюсь найти решение, предложенное в другом потоке ( заменить дублирующиеся значения на NA в данных временных рядов, используя dplyr ), используя data.table. Однако я получаю только первое дублированное значение в каждом столбце, замененное на «NA», но не последующие.

cols <- colnames(dt)
dt[, lapply(.SD, function(x) replace(x, anyDuplicated(x), NA)), .SDcols = cols]
> dt
      A    B    C
1:   5p   1c   4f
2:   3p   4r    5
3: <NA> <NA> <NA>
4:   6y <NA>    5
5: <NA> <NA>   4m

Как мне изменить код, чтобы заменить все дубликаты?

Ответы [ 2 ]

1 голос
/ 17 января 2020

Использование duplicated

library(data.table)
dt[, lapply(.SD, function(x) replace(x, duplicated(x), NA))]

#      A    B    C
#1:   5p   1c   4f
#2:   3p   4r    5
#3: <NA> <NA> <NA>
#4:   6y <NA> <NA>
#5: <NA> <NA>   4m
0 голосов
/ 17 января 2020

Если я правильно понимаю, OP хочет удалить все дублированные записи из каждого столбца, чтобы данные полезной нагрузки заполнялись сверху вниз, а NA располагаются внизу. (Это отличается от другого вопроса OP ).

собственная попытка OP, а также ответ Ронака оставляют NA s перемежающимися со значениями столбца.

Если допустимо избавиться от строк со всеми NA (например, na.omit()), я предлагаю изменить форму на длинный формат, удалить повторяющиеся записи и изменить обратно на широкий формат:

library(data.table)
dcast(unique(melt(dt, measure.vars = names(dt), na.rm = TRUE)), rowid(variable) ~ variable)[
  , variable := NULL][]

    A    B  C
1: 5p   1c 4f
2: 3p   4r  5
3: 6y <NA> 4m

Если требуется, чтобы результат имел то же число строк, что и раньше, ответ Ронака необходимо изменить:

library(data.table)
dt[, (names(dt)) := lapply(.SD, function(x) sort(replace(x, duplicated(x), NA), na.last = TRUE))][]

dt
      A    B    C
1:   3p   1c   4f
2:   5p   4r   4m
3:   6y <NA>    5
4: <NA> <NA> <NA>
5: <NA> <NA> <NA>

Обратите внимание, что здесь dt изменяется на месте.

Примечание:

Обычно, если данные хранятся в табличном формате, таком как data.frame, date.table или tibble, каждая переменная столбец, каждое наблюдение является строкой . Здесь записи удаляются из столбцов независимо от других столбцов, в результате чего получается «неровная» таблица данных с «рваным дном».

ИМХО, это сильный показатель того, что табличный формат может быть не лучшим выбором. Возможно, список векторов с различным количеством элементов был бы более подходящим. Тем не менее, без понимания основной проблемы это чистая догадка.

dl <- as.list(dt)
lapply(dl, unique)
$A
[1] "5p" "3p" "6y" NA  

$B
[1] "1c" "4r" NA  

$C
[1] "4f" "5"  "4m"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...