Есть много сообщений о замене ценностей NA. Я знаю, что можно заменить NA в следующей таблице / кадре следующим:
x[is.na(x)]<-0
Но что, если я хочу ограничить его только определенными столбцами? Я покажу вам пример.
Во-первых, давайте начнем с набора данных.
set.seed(1234)
x <- data.frame(a=sample(c(1,2,NA), 10, replace=T),
b=sample(c(1,2,NA), 10, replace=T),
c=sample(c(1:5,NA), 10, replace=T))
Который дает:
a b c
1 1 NA 2
2 2 2 2
3 2 1 1
4 2 NA 1
5 NA 1 2
6 2 NA 5
7 1 1 4
8 1 1 NA
9 2 1 5
10 2 1 1
Хорошо, поэтому я хочу ограничить замену только столбцами «a» и «b». Моя попытка была:
x[is.na(x), 1:2]<-0
и:
x[is.na(x[1:2])]<-0
Что не работает.
Моя попытка data.table, где y<-data.table(x)
, очевидно, никогда не сработала:
y[is.na(y[,list(a,b)]), ]
Я хочу передать столбцы внутри аргумента is.na, но это явно не сработает.
Я хотел бы сделать это в data.frame и data.table. Моя конечная цель - перекодировать 1: 2 в 0: 1 в 'a' и 'b', сохраняя при этом 'c' таким, какой он есть, поскольку это не логическая переменная. У меня куча столбцов, поэтому я не хочу делать это одну за другой. И я просто хотел бы знать, как это сделать.
У вас есть какие-нибудь предложения?
x[, 1:2][x[, 1:2] == 1] <- 0
x
принимает матрицу в качестве своего первого члена только при назначении? Эта функция где-то задокументирована? Также я думаю, что вы забыли поставить запятую перед векторами с именами столбцов во втором примере.[
, он извлечет указанные столбцы (см. Stackoverflow.com/a/21137524/1201032 ). Я надеюсь, что это ответит на ваш вопрос, но в будущем, пожалуйста, избегайте комментировать очень старые ответы, подобные этому; вместо этого разместите новый вопрос.In both cases, 1:2 or c("a", "b") can be replaced by a pre-defined vector.
Когда я использовал такой предопределенный вектор,x[Vpredefined][is.na(x[Vpredefined])] <- 0
это дает мне ошибкуИзменить 2020-06-15
Начиная с
data.table
1.12.4 (октябрь 2019 г.), для этого былиdata.table
добавлены две функции:nafill
иsetnafill
.nafill
работает с колоннами:cols = c('a', 'b') y[ , (cols) := lapply(.SD, nafill, fill=0), .SDcols = cols]
setnafill
работает с таблицами (замены происходят по ссылке / на месте)setnafill(y, cols=cols, fill=0) # print y to show the effect y[]
Это также будет более эффективным, чем другие варианты; см.
?nafill
для получения дополнительной информации, версииNA
вменения для временных рядов с переносом последнего наблюдения (LOCF) и переносом следующего наблюдения назад (NOCB) .Это будет работать для вашей
data.table
версии:for (col in c("a", "b")) y[is.na(get(col)), (col) := 0]
В качестве альтернативы, как указывает ниже Дэвид Аренбург, вы можете использовать
set
(побочное преимущество - вы можете использовать его либо на,data.frame
либоdata.table
):for (col in 1:2) set(x, which(is.na(x[[col]])), col, 0)
источник
out <- x
чтобы избежать недопонимания с x data.frame из вопроса? В противном случае это еще более короткая команда:y[, (cols):=lapply(.SD, function(i){i[is.na(i)] <- 0; i}), .SDcols = cols]
пропуск имени переменной 'out' и использование 'x'.Основываясь на ответе @Robert McDonald
tidyr::replace_na()
, вот несколькоdplyr
вариантов управления тем, какие столбцыNA
заменяются:library(tidyverse) # by column type: x %>% mutate_if(is.numeric, ~replace_na(., 0)) # select columns defined in vars(col1, col2, ...): x %>% mutate_at(vars(a, b, c), ~replace_na(., 0)) # all columns: x %>% mutate_all(~replace_na(., 0))
источник
Error in replace_na(., 0) : argument "value" is missing, with no default
. Есть предложения, что изменить?Теперь это тривиально в tidyr с помощью replace_na (). Похоже, что функция работает как с data.tables, так и с data.frames:
tidyr::replace_na(x, list(a=0, b=0))
источник
Не уверен, что это более сжато, но эта функция также найдет и разрешит замену NA (или любого другого значения) в выбранных столбцах таблицы data.table:
update.mat <- function(dt, cols, criteria) { require(data.table) x <- as.data.frame(which(criteria==TRUE, arr.ind = TRUE)) y <- as.matrix(subset(x, x$col %in% which((names(dt) %in% cols), arr.ind = TRUE))) y }
Чтобы применить это:
y[update.mat(y, c("a", "b"), is.na(y))] <- 0
Функция создает матрицу выбранных столбцов и строк (координаты ячеек), которые соответствуют критериям ввода (в данном случае is.na == TRUE).
источник
Мы можем решить эту проблему
data.table
с помощьюtidyr::repalce_na
функции иlapply
library(data.table) library(tidyr) setDT(df) df[,c("a","b","c"):=lapply(.SD,function(x) replace_na(x,0)),.SDcols=c("a","b","c")]
Таким образом, мы также можем решить вставить столбцы со
NA
строкой. Сначала мыreplace_na(x,"")
, потом можем использоватьstringr::str_c
для объединения столбцов!источник
Для конкретного столбца есть альтернатива с
sapply
DF <- data.frame(A = letters[1:5], B = letters[6:10], C = c(2, 5, NA, 8, NA)) DF_NEW <- sapply(seq(1, nrow(DF)), function(i) ifelse(is.na(DF[i,3]) == TRUE, 0, DF[i,3])) DF[,3] <- DF_NEW DF
источник
это очень удобно с {data.table} и {stringr}
library(data.table) library(stringr) x[, lapply(.SD, function(xx) {str_replace_na(xx, 0)})]
К вашему сведению
источник
Начиная с data.table y, вы можете просто написать:
y[, (cols):=lapply(.SD, function(i){i[is.na(i)] <- 0; i}), .SDcols = cols]
Не забудьте
library(data.table)
перед созданиемy
и запуском этой команды.источник
это отлично работает для меня
DataTable DT = new DataTable(); DT = DT.AsEnumerable().Select(R => { R["Campo1"] = valor; return (R); }).ToArray().CopyToDataTable();
источник