Използване на ifelse за премахване на нежелани редове от набора от данни в R

Имам набор от данни, където искам да премахна случаите на месец 11 през първата година на наблюдение за няколко от моите индивиди. Възможно ли е да направите това с ifelse? Нещо като:

ifelse(ID=="1" & Month=="11" and Year=="2006", "remove these rows",  
  ifelse(ID=="2" & Month=="11" & Year=="2007", "remove these rows",   
         "nothing"))  

Както винаги, всяка помощ се оценява! :)


person ego_    schedule 17.09.2012    source източник
comment
Вероятно има много добри отговори на този въпрос, всички от които биха имали голяма полза от наличието на възпроизводим пример.   -  person BenBarnes    schedule 17.09.2012
comment
Колко лица премахвате? 2 или 3, или повече? (Ако е повече, трябва да използвате %in%).   -  person David Robinson    schedule 17.09.2012


Отговори (2)


Дори не се нуждаете от ifelse(), ако всичко, което искате, е индикатор за това кой да премахнете или не.

ind <- (Month == "11") &
           ((ID == "1" & Year == "2006") | (ID == "2" & Year == "2007"))

ind ще съдържа TRUE, ако Month е "11" и ако някоя от другите две подклаузи е TRUE.

След това можете да пуснете тези примери, като използвате !ind във всяка операция на подмножество чрез [ или subset().

dat <- data.frame(ID = rep(c("1","2"), each = 72),
                  Year = rep(c("2006","2007","2008"), each = 24),
                  Month = rep(as.character(1:12), times = 3))
ind <- with(dat, (Month == "11") & ((ID == "1" & Year == "2006") |
                                    (ID == "2" & Year == "2007")))
ind
dat2 <- dat[!ind, ]

Което дава

R> ind
  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
 [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
 [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
[109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
[121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
R>     dat2 <- dat[!ind, ]
R> nrow(dat)
[1] 144
R> nrow(dat2)
[1] 140

което е правилно по отношение на примерните данни/

person Gavin Simpson    schedule 17.09.2012

data.table решение, което ще бъде ефективно време и памет (и малко по-малко кодиране). Ще се мащабира добре за големи набори от данни.

Ако колоните бяха цяло число, а не фактор

library(data.table)
DT <- data.table(ID = rep(1:2, each = 72),
          Year = rep(2006:2008, each = 24),
          Month = rep(1:12, times = 3))
# or you could use:   DT <- as.data.table(dat)
setkey(DT,ID,Year,Month)
DT[-DT[J(1:2,2006:2007,11),which=TRUE]]
person mnel    schedule 17.09.2012
comment
Благодаря за вниманието -- имах проблеми с характер/фактор и -J(...) - person mnel; 18.09.2012
comment
А, не забелязах аспекта характер/фактор. Ако колоните на DT са символен тип, тогава : DT[-DT[J(c("1","2"),as.character(2006:2007),"11"),which=TRUE]]. Ако те са фактор, тогава това също ще работи (с предупреждение, мисля) или като фактор: DT[-DT[J(factor(1:2),factor(2006:2007),factor(11)),which=TRUE]]. - person Matt Dowle; 18.09.2012