2012-02-24 15 views
40

Mam macierz (2601 na 58) szacunków stężeń cząstek stałych z modelu jakości powietrza. Ponieważ rzeczywiste monitory jakości powietrza nie mogą mierzyć poniżej 0,1 ug/L, muszę zastąpić wszystkie wartości w mojej macierzy, które są <0.1 wartością zero/NA/null.Zastąp wszystkie wartości w macierzy <0,1 za pomocą 0

Ktoś zasugerował ifelse(test, true, false) z logiczną instrukcją, ale kiedy próbuję to, usuwa wszystko.

+2

Pytanie o to, co zastąpić wartości ujemne lub zerowe, jest interesujące. Ponieważ wiele modeli jest zbudowanych na zasadzie log (y), często zastępuję je punktem środkowym między dolnym limitem normalnym i zerem. (Prawdopodobnie wtórne pytanie najlepiej postawione na stats.exchange.) –

+0

@Dwin, +1 do tego komentarza. Chciałbym zobaczyć to drugie pytanie, a jego odpowiedzi na crossvalidate.com –

+0

to ciekawy komentarz - widzę to, co mówisz ... W kontekście używam tych wartości w regresji z danymi z oddziału ratunkowego (badanie epidemiologiczne populacji). Wyjaśnienie, które mi podano, dlaczego zastąpić <0,1 0, było takie, że nie chcemy przeceniać efektu ... czegoś związanego z "zero zawyżone"? – mEvans

Odpowiedz

39

ifelse powinno działać:

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

Ale wybrałbym odpowiedź Harlan nad kopalni.

mat[mat < 0.1] <- NA 
+0

Coś z ifelse wydaje mi się, że zmieniam moją matrycę w wektor ... czy mógłbym w jakiś sposób przekształcić ją w matrycę? – mEvans

+1

@mEvans to nie dla mnie! jeśli wkleję mój kod, odzyskaję macierz ... ale tak, zawsze możesz przekonwertować 'wektor' na' macierz' używając 'matrix (mat)'. Spójrz na wszystkie opcjonalne argumenty do 'matrix'. Ale, jak powiedziałem w mojej odpowiedzi, myślę, że odpowiedź Harlana jest najlepsza przez długie ujęcie. – Justin

56
X[X < .1] <- 0 

(lub NA, chociaż 0 brzmi bardziej odpowiednie w tym przypadku).

Macierze są tylko wektory o wymiarach, dzięki czemu można je traktować jak wektorze Po przypisaniu do nich. W tym przypadku tworzysz wektor logiczny na X, który wskazuje małe wartości i przypisuje prawą stronę każdemu elementowi, który ma PRAWDA.

+0

Czy możesz to zrobić tylko dla niektórych kolumn? Zastępuje inne wartości w innych kolumnach (takich jak daty i czasy itp.), Gdy uruchamiam je na całej macierzy. – mEvans

+2

Dla podzbioru cols, możesz użyć: 'X [, c (1,3,5)] <- apply (X [, c (1,3,5)], 2, function (x) ifelse (x <0,1, 0, x)) '(dla kolumn 1, 3 i 5). – jbaums

+7

@mEvans: jeśli masz różne typy danych w różnych kolumnach, oznacza to, że prawdopodobnie masz ramkę danych, a nie macierz. Są to różne stworzenia w R, chociaż wiele operacji będzie działać z obydwoma. Powinieneś sprawdzić, co jest twoim zestawem danych, zanim zrobisz cokolwiek innego, ponieważ prawdopodobnie później zaoszczędzisz dużo bólu. –

1

Wystarczy, aby zapewnić (moim zdaniem) interesującą alternatywę:

Jeśli trzeba zacisnąć wartości są więc nigdy mniejsza niż wartość, można użyć pmax:

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

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

... To jednak nie działa w twoim przypadku, ponieważ chcesz, aby wartości < 0.1 stały się równe 0.

1

Inne równoważne metody:

let:

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

brute force (wychowawcza)

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 
    } 

Jeśli istnieją wartości brakujących (NA) wm, pomijając !is.na da błędów.

inny sposób: używając recode w pakiecie car:

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

nie można określić ścisłej nierówności tutaj, więc dlatego nie ma grono 9. umieścić więcej dziewiątek i zamienia się w 0,1. lo jest wygodą recode, która daje minimalną wartość (usuwanie NA).

1

Roztwór 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: kod rm.neg można ekstrahować i uproszczone, tak aby nie trzeba wywołanie plyr, która jest używana do utworzenia funkcji colwise.

1

Myślę, że przekonasz się, że "ifelse" nie jest operacją wektorową (faktycznie działa jako pętla), a więc jest to kolejność wielkości wolniejsza niż odpowiednik wektorowy. R faworyzuje operacje wektorowe, dlatego zastosowanie, mapply, sapply są błyskawiczne dla pewnych obliczeń.

Małe zbiory danych, nie jest problem, ale jeśli masz tablicę o długości 100k lub więcej, możesz iść i ugotować pieczoną kolację, zanim skończy się na jakiejkolwiek metodzie z udziałem pętli.

Poniższy kod powinien zadziałać.

Dla wektora

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

Dla Dataframe lub Matrix.

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

Kolejny szybki sposób, za pośrednictwem funkcji pmax i Pmin, to czapki wpisów pomiędzy 0 a 1 i można umieścić matrycę lub dataframe jako pierwszy argument żadnych problemów.

ulbound <- function(v,MAX=1,MIN=0) pmin(MAX,pmax(MIN,v)) 
Powiązane problemy