Если я правильно понимаю, 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"