Ответ 1
ifelse
должен работать:
mat <- matrix(runif(100),ncol=5)
mat <- ifelse(mat<0.1,NA,mat)
Но я бы выбрал Харлан на мой вопрос.
mat[mat < 0.1] <- NA
У меня есть матрица (2601 на 58) оценок концентрации твердых частиц по модели качества воздуха. Поскольку реальные мониторы качества воздуха не могут измеряться ниже 0,1 мкг/л, мне нужно заменить все значения в моей матрице, которые <0.1
имеют нулевое значение /NA/null.
Кто-то предложил ifelse(test, true, false)
с логическим выражением, но когда я попробую это, он удалит все.
ifelse
должен работать:
mat <- matrix(runif(100),ncol=5)
mat <- ifelse(mat<0.1,NA,mat)
Но я бы выбрал Харлан на мой вопрос.
mat[mat < 0.1] <- NA
X[X < .1] <- 0
(или NA, хотя 0 в этом случае более подходит).
Матрицы - это просто векторы с размерами, поэтому вы можете относиться к ним как к вектору при назначении им. В этом случае вы создаете логический вектор над X, который указывает малые значения, и присваивает правой стороне каждому элементу TRUE.
Просто чтобы предоставить (на мой взгляд) интересную альтернативу:
Если вам нужно закрепить значения, чтобы они никогда не были меньше значения, вы можете использовать pmax
:
set.seed(42)
m <- matrix(rnorm(100),10)
m <- pmax(m, 0) # clamp negative values to 0
... Это не совсем работает в вашем случае, так как вам нужны значения < 0,1, чтобы стать 0.
Другие эквивалентные методы:
пусть:
M=matrix(rnorm(10*10), 10, 10)
Грубая сила (воспитательная)
for (i in 1:nrow(M)) {
for (j in 1:ncol(M)) if (M[i,j]<0.1 & !is.na(M[i,j]) ) M[i,j]=NA
}
Если в M отсутствуют значения (NA), опускание !is.na
приведет к ошибкам.
Другой способ: использовать recode
в пакете car
:
library(car)
recode(M, "lo:0.099999=NA")
Невозможно указать строгое неравенство, так что почему-то пучок из 9. Положите больше девяток, и он превратится в 0,1. lo
- это удобство перекодировки, которое дает минимальное значение (удаление NA).
Решение data.frame:
if(!require(plyr)){
install.packages("plyr")}
rm.neg<-colwise(function(x){
return(ifelse(x < 0.1, 0, x))})
rm.neg(data.frame(mat))
PS: код для rm.neg может быть извлечен и упрощен, чтобы не требовать вызова plyr, который используется для создания произвольной функции.
Я думаю, вы обнаружите, что "ifelse" не является векторной операцией (фактически выполняющейся как цикл), и поэтому это порядки величин медленнее векторного эквивалента. R поддерживает векторные операции, поэтому применение, mapply, sapply молниеносно для определенных вычислений.
Малые наборы данных - это не проблема, но если у вас есть массив длиной 100 тыс. или более, вы можете пойти и приготовить обжаренный ужин до того, как он закончится любым способом, связанным с циклом.
Нижеприведенный код должен работать.
Для вектора
minvalue <- 0
X[X < minvalue] <- minvalue
Для Dataframe или Matrix.
minvalue <- 0
n <- 10 #change to whatever.
columns <- c(1:n)
X[X[,columns] < minvalue,columns] <- minvalue
Еще один быстрый метод, через функции pmax и pmin, устанавливает значения между 0 и 1, и вы можете поместить матрицу или dataframe в качестве первого аргумента без проблем.
ulbound <- function(v,MAX=1,MIN=0) pmin(MAX,pmax(MIN,v))