web-dev-qa-db-ja.com

行列<0.1のすべての値を0に置き換えます

大気質モデルからの粒子状物質濃度の推定値のマトリックス(2601 x 58)があります。実際の大気質モニターは0.1 ug/L未満を測定できないため、<0.1であるマトリックス内のすべての値をゼロ/ NA/null値に置き換える必要があります。

誰かがifelse(test, true, false)を論理ステートメントで提案しましたが、これを試みるとすべてが削除されます。

49
mEvans

ifelseは動作するはずです:

mat <- matrix(runif(100),ncol=5)
mat <- ifelse(mat<0.1,NA,mat)

しかし、私は私よりもハーランの答えを選びます。

mat[mat < 0.1] <- NA
56
Justin
X[X < .1] <- 0

(または、NA。ただし、この場合は0がより適切に聞こえます。)

行列は次元を持つ単なるベクトルであるため、それらを割り当てるときにベクトルのように扱うことができます。この場合、小さな値を示すブールベクトルをX上に作成し、TRUEである各要素に右側を割り当てます。

65
Harlan

「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
ADP

(私の意見では)興味深い代替案を提供するために:

値が値より小さくならないように値をクランプする必要がある場合は、pmaxを使用できます。

set.seed(42)
m <- matrix(rnorm(100),10)

m <- pmax(m, 0) # clamp negative values to 0

...これは、0.1未満の値を0にしたいので、あなたのケースではまったく機能しません。

1
Tommy

さらに同等の方法:

させてください:

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を省略するとエラーが発生します。

別の方法:パッケージrecodecarを使用する:

library(car)
recode(M, "lo:0.099999=NA")

ここで厳密な不等式を指定することはできません。そのため、9がたくさんあります。さらに9を入れると、0.1になります。 loは再コード化の便利さで、最小値を提供します(NAを削除します)。

1
p_barill

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のコードは、colwise関数の作成に使用されるplyrの呼び出しを必要としないように抽出および簡素化できます。