У меня есть таблица данных DT
, и я хочу заменить ведущие нули каждого столбца на NA
.
for (n in 1:ncol(DT)) {
tmp <- as.vector(unlist(DT[,..n]))
tmp[cumsum(tmp) == 0] <- NA
}
Но теперь я не знаю, как вернуть вектор tmp
в n-й столбец DT
.
Также неудовлетворительно то, как создается tmp
.
Я не знаю, подразумеваете ли вы под «ведущими нулями» «первый ноль каждого столбца». В этом случае вы можете сделать что-то вроде этого:
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))
Разве вариант
sapply/vapply
сstringr::str_replace_all
илиgsub
не справится с этой задачей?