Domanda Sostituisci tutti i valori in una matrice <0,1 con 0


Ho una matrice (2601 per 58) delle stime di concentrazione del particolato da un modello di qualità dell'aria. Poiché i monitor della qualità dell'aria della vita reale non possono misurare sotto 0,1 ug / L, ho bisogno di sostituire tutti i valori nella mia matrice che sono <0.1 con un valore zero / NA / null.

Qualcuno ha suggerito ifelse(test, true, false) con una dichiarazione logica, ma quando provo questo cancella tutto.


44
2018-02-24 23:39


origine


risposte:


ifelse dovrebbe funzionare:

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

Ma sceglierei la risposta di Harlan sulla mia.

mat[mat < 0.1] <- NA

44
2018-02-24 23:48



X[X < .1] <- 0

(o NA, anche se suona in questo caso più appropriato).

Le matrici sono solo vettori con dimensioni, quindi puoi trattarli come un vettore quando li assegni. In questo caso, stai creando un vettore booleano su X che indica i valori piccoli e assegna il lato destro a ciascun elemento che è VERO.


59
2018-02-24 23:47



Solo per fornire un'alternativa interessante (secondo me):

Se è necessario bloccare i valori in modo che non siano mai inferiori a un valore, è possibile utilizzarli pmax:

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

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

... Questo non funziona nel tuo caso anche se vuoi che i valori <0.1 diventino 0.


1
2018-02-25 00:52



Ulteriori metodi equivalenti:

permettere:

M=matrix(rnorm(10*10), 10, 10)

Forza bruta (educativa)

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
    }

Se ci sono valori mancanti (NA) in M, omettendo !is.na darà errori.

Un altro modo: usare recode nel pacchetto car:

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

Non è possibile specificare una disuguaglianza rigorosa qui, ecco perché c'è un mucchio di 9. Metti più nove e si trasforma in 0.1. lo è una comodità di ricodifica, che fornisce il valore minimo (rimozione di NA).


1
2018-03-04 16:03



Una soluzione 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: il codice per rm.neg può essere estratto e semplificato in modo da non richiedere una chiamata a plyr, che viene utilizzata per creare la funzione colwise.


1
2018-06-21 14:24



Penso che scoprirai che "ifelse" non è un'operazione vettoriale (in realtà si comporta come un loop), e quindi gli ordini di grandezza sono più lenti del vettore equivalente. R favorisce le operazioni vettoriali, che è il motivo per cui applicare, mapply, sapply è un fulmine veloce per determinati calcoli.

Dataset di piccole dimensioni, non un problema, ma se si dispone di una serie di lunghezze pari o superiori a 100k, è possibile andare a cucinare una cena arrosto prima che finisca con qualsiasi metodo che implichi un ciclo.

Il codice seguente dovrebbe funzionare.

Per il vettore

minvalue <- 0
X[X < minvalue] <- minvalue

Per Dataframe o Matrix.

minvalue <- 0
n <- 10 #change to whatever.
columns <- c(1:n)
X[X[,columns] < minvalue,columns] <- minvalue

Un altro metodo veloce, tramite le funzioni pmax e pmin, questo tappi le voci tra 0 e 1 e puoi mettere una matrice o un dataframe come primo argomento senza problemi.

ulbound <- function(v,MAX=1,MIN=0) pmin(MAX,pmax(MIN,v))

1
2017-12-06 11:19