我有一个空气质量模型的颗粒物浓度估算矩阵(2601乘58)。由于现实生活中的空气质量监测器无法测量低于0.1 ug / L,我需要将<0.1
的所有值替换为零/ NA / null值。
有人建议ifelse(test, true, false)
使用逻辑语句,但是当我尝试这样做时会删除所有内容。
答案 0 :(得分:64)
X[X < .1] <- 0
(或NA,虽然在这种情况下0听起来更合适。)
矩阵只是具有维度的向量,因此您可以在分配时将它们视为向量。在这种情况下,您将在X上创建一个指示较小值的布尔向量,并将右侧分配给每个都为TRUE的元素。
答案 1 :(得分:54)
ifelse
应该有效:
mat <- matrix(runif(100),ncol=5)
mat <- ifelse(mat<0.1,NA,mat)
但我会选择Harlan对我的回答。
mat[mat < 0.1] <- NA
答案 2 :(得分:1)
只是提供(在我看来)有趣的替代方案:
如果您需要限制值以使它们永远不会小于某个值,则可以使用pmax
:
set.seed(42)
m <- matrix(rnorm(100),10)
m <- pmax(m, 0) # clamp negative values to 0
...这在你的情况下并不常用,因为你想要值&lt; 0.1变为0。
答案 3 :(得分:1)
进一步的等效方法:
令:
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。把更多的9和它变成0.1。 lo
是recode的便利,它提供了最小值(删除NA)。
答案 4 :(得分:1)
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,plyr用于创建colwise函数。
答案 5 :(得分:1)
我认为你会发现'ifelse'不是一个向量运算(它实际上是一个循环),所以它的数量级比向量等价的慢。 R赞成向量运算,这就是为什么对某些计算应用,mapply,sapply是快速闪电的原因。
小数据集,不是问题,但如果你有一个长度为100k或更长的数组,你可以在任何涉及循环的方法完成之前去做一顿烤晚餐。
以下代码应该有效。
对于矢量
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之间的条目,你可以把矩阵或数据框作为第一个参数没有问题。
ulbound <- function(v,MAX=1,MIN=0) pmin(MAX,pmax(MIN,v))