将矩阵 <0.1 中的所有值替换为 0
Posted
技术标签:
【中文标题】将矩阵 <0.1 中的所有值替换为 0【英文标题】:Replace all values in a matrix <0.1 with 0 【发布时间】:2012-03-15 10:14:25 【问题描述】:我有一个来自空气质量模型的颗粒物浓度估计矩阵(2601 x 58)。因为现实生活中的空气质量监测器无法测量到低于 0.1 ug/L,所以我需要将矩阵中所有 <0.1
的值替换为零/NA/null 值。
有人建议ifelse(test, true, false)
有一个合乎逻辑的陈述,但是当我尝试这样做时,它会删除所有内容。
【问题讨论】:
关于用什么替换负值或零值的问题是一个有趣的问题。因为很多模型都是基于 log(y) 构建的,所以我经常将它们替换为正常下限和零之间的中点。 (可能是 stats.exchange 上最好的次要问题。) @Dwin,对该评论 +1。我想看看第二个问题,它是 crossvalidated.com 上的答案 这是一个有趣的评论——我明白你在说什么......作为上下文,我在急诊科数据(人口流行病学研究)的回归中使用这些值。为什么用 0 替换 @mEvans:很有趣。 “零膨胀”是处理太多零的模型的术语,因此您很可能正在创建需要分析以正确处理“零膨胀数据”的数据情况 这个问题的任何data.frame解决方案? 【参考方案1】:我想你会发现'ifelse' 不是一个向量运算(它实际上是一个循环),所以它比等效向量慢几个数量级。 R 支持向量运算,这就是为什么 apply、mapply、sapply 在某些计算中速度快的原因。
小数据集,不是问题,但如果你有一个长度为 100k 或更长的数组,你可以在任何涉及循环的方法下做一顿烤肉。
下面的代码应该可以工作。
对于矢量
minvalue <- 0
X[X < minvalue] <- minvalue
对于数据框或矩阵。
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))
【讨论】:
【参考方案2】: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函数的。
【讨论】:
【参考方案3】:其他等效方法:
让:
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
会出错。
另一种方式:在包car
中使用recode
:
library(car)
recode(M, "lo:0.099999=NA")
这里不能指定严格的不等式,所以这就是为什么会有一堆 9。放更多的 9 会变成 0.1。 lo
是 recode 的一种方便,它给出了最小值(去除 NA)。
【讨论】:
【参考方案4】:只是为了提供一个(在我看来)有趣的替代方案:
如果您需要限制值以使它们永远不会小于某个值,您可以使用pmax
:
set.seed(42)
m <- matrix(rnorm(100),10)
m <- pmax(m, 0) # clamp negative values to 0
...这在您的情况下不太适用,因为您希望值
【讨论】:
【参考方案5】:ifelse
应该可以工作:
mat <- matrix(runif(100),ncol=5)
mat <- ifelse(mat<0.1,NA,mat)
但我会选择 Harlan 的答案而不是我的答案。
mat[mat < 0.1] <- NA
【讨论】:
ifelse 的问题是它似乎把我的矩阵变成了一个向量......我能以某种方式将它重新塑造成一个矩阵吗? @mEvans 它不适合我!如果我粘贴我的代码,我会返回矩阵...但是是的,您始终可以使用matrix(mat)
将vector
转换为matrix
。查看matrix
的所有可选参数。但是,就像我在回答中所说的那样,我认为 Harlan 的回答是最好的。【参考方案6】:
X[X < .1] <- 0
(或 NA,虽然在这种情况下 0 听起来更合适。)
矩阵只是具有维度的向量,因此在分配给它们时可以将它们视为向量。在这种情况下,您将在 X 上创建一个布尔向量来指示小值,并将右侧分配给每个为 TRUE 的元素。
【讨论】:
您可以只对某些列执行此操作吗?当我在整个矩阵上运行它时,它会替换其他列中的其他值(如日期和时间等)。 对于 cols 的子集,您可以使用:X[, c(1,3,5)] <- apply(X[, c(1,3,5)], 2, function(x) ifelse(x < 0.1, 0, x))
(对于第 1、3 和 5 列)。
@mEvans:如果您在不同的列中有不同类型的数据,这意味着您可能有一个数据框,而不是矩阵。这些是 R 中不同的小动物,尽管许多操作都适用于两者。您应该在做任何其他事情之前检查您的数据集是什么,因为这可能会在以后为您节省很多痛苦。
@jbaums 适用于矩阵,但不适用于向量。例如,案例 X[,1](仅使用 1 列)失败,因为 dim(X[,1]) = NULL。困扰我的是函数描述说它适用于向量(有长度,但没有维度)和矩阵(有长度和维度)。
@GuilhermeSalomé - 您可以添加 drop=FALSE
以确保它适用于单个列。以上是关于将矩阵 <0.1 中的所有值替换为 0的主要内容,如果未能解决你的问题,请参考以下文章
R语言dplyr包将dataframe中的NA值替换(replace)为0实战:所有NA值替换(replace)为0具体列的NA值替换(replace)为0若干列的NA值替换(replace)为0