Удалите ведущие нули каждого столбца таблицы data.table

У меня есть таблица данных DT, и я хочу заменить ведущие нули каждого столбца на NA.

for (n in 1:ncol(DT)) {
  tmp <- as.vector(unlist(DT[,..n]))
  tmp[cumsum(tmp) == 0] <- NA
}

Но теперь я не знаю, как вернуть вектор tmp в n-й столбец DT.

Также неудовлетворительно то, как создается tmp.

Разве вариант sapply/vapply с stringr::str_replace_all или gsub не справится с этой задачей?

Nautica 09.12.2018 11:45
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
347
4

Ответы 4

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

DT[, lapply(.SD, function(x) ifelse(x == 0 & !duplicated(x), NA, x))]

#     n  m
# 1: NA  1
# 2:  1 NA
# 3:  0  2

Если вы имели в виду «любой ноль в первой строке», то:

DT[, lapply(.SD, function(x) ifelse(cumsum(x) == 0, NA, x))]

#     n m
# 1: NA 1
# 2:  1 0
# 3:  0 2

Данные:

DT <- data.table(n = c(0, 1, 0), m = c(1, 0, 2))

DT

#    n m
# 1: 0 1
# 2: 1 0
# 3: 0 2

Похоже, вы пытаетесь заменить все начальные строки с нулевым значением на NA для каждого столбца.

В этом случае, вероятно, лучше всего использовать set:

for (jj in names(DT)) {
  set(DT, 1:(which.min(DT[[jj]] == 0) - 1L), jj, NA)
}

NB: Возможно, вам придется быть более осторожными с NA, поскольку вам нужно будет предоставить правильныйNA в соответствии с типом столбца.

types = sapply(DT, typeof)
for (jj in names(DT)) {
  set(DT, 1:(which.min(DT[[jj]] == 0) - 1L), jj,
      switch(types[jj],
             'logical'   = NA,
             'integer'   = NA_integer_,
             'numeric'   = NA_real_,
             'character' = NA_character_,
             'complex'   = NA_complex_,
             stop("No known NA value for type", types[jj]))
       )
}

Если вы хотите заменить каждый первый ноль для каждого столбца на NA:

DT <- data.table(A = c(0, 1, 0, 2), B = c(1, 0, 2, 0), C = c(1, 1, 2, 0))
DT

# Output
  A B C
1 0 1 1
2 1 0 1
3 0 2 2
4 2 0 0

# DT to DF
df <- as.data.frame(DT)

# Replacing each first zero for each column with NA
for (col in 1:ncol(df)){
  df[min(which(df[, col] == 0)), col] <- NA
}
df

# Output
   A  B  C
1 NA  1  1
2  1 NA  1
3  0  2  2
4  2  0 NA

Вот альтернативная версия, которая также будет работать с базовым R (то есть, если бы DT был data.frame:

DT[!sapply(DT, duplicated) & DT == 0] <- NA
> DT
    n  m
1: NA  1
2:  1 NA
3:  0  2

Данные:

DT <- data.table(n = c(0, 1, 0), m = c(1, 0, 2))

Другие вопросы по теме