Как сгенерировать двоичную переменную в соответствии с условиями других переменных?

Еще раз приношу извинения за вопрос такого типа, но мир R настолько велик, что иногда я чувствую себя потерянным, даже если я прочитал одну из лучших книг, связанных с R. У меня есть следующая БД

ID=rep((1:3),3)
x<-as.Date("2013-1-1")
y<-as.Date("2013-1-2")
z<-as.Date("2013-1-3")
DATE<-c(x,x,x,y,x,y,z,z,z)
TRAP<-c(1,1,1,3,2,3,2,1,3)
IN<-data.frame(ID,DATE,TRAP)

и я хотел бы создать двоичную переменную (РЕЗУЛЬТАТ) в соответствии со следующими условиями: если ДАТА и ЛОВУШКА одинаковы для разных идентификаторов, то РЕЗУЛЬТАТ>y иначе РЕЗУЛЬТАТ>n, как это

RESULT<-c("y","y","y","y","n","y","n","n","n")
OUT<-cbind(IN,RESULT)

Я думаю, что следует использовать функцию ifelse, но я не знаю, как явно указать условие контроля равенства для каждого идентификатора... Как всегда, каждое предложение приветствуется!


person stefano    schedule 22.04.2013    source источник
comment
Извините, но я не могу найти логику вашего RESULT...   -  person juba    schedule 22.04.2013
comment
Я тоже, но это, кажется, близко: library(plyr); IN$ID2 <- rep(1:3,each=3); ddply(IN,.(ID2),transform,RESULT=(TRAP==TRAP[1] & DATE==DATE[1]))   -  person Roland    schedule 22.04.2013
comment
@juba, опс, в прошлом году вы ошиблись в результате, поэтому я уже редактирую результат. По сути, если ловушка и дата совпадают, результатом будет y, иначе n. Я надеюсь, что я достаточно ясно, извините за ошибку!   -  person stefano    schedule 22.04.2013
comment
@ Роланд, я пробую твое решение, но запись номер 7 неверна. Я имею в виду, что это должно быть FALSE›n вместо TRUE›y   -  person stefano    schedule 22.04.2013


Ответы (2)


Вот как это сделать с помощью plyr :

R> ddply(IN, .(DATE,TRAP), transform, RESULT=ifelse(length(ID)>1,"y","n"))
  ID       DATE TRAP RESULT
1  1 2013-01-01    1      y
2  2 2013-01-01    1      y
3  3 2013-01-01    1      y
4  2 2013-01-01    2      n
5  1 2013-01-02    3      y
6  3 2013-01-02    3      y
7  2 2013-01-03    1      n
8  1 2013-01-03    2      n
9  3 2013-01-03    3      n

Обратите внимание, что порядок строк был изменен.


Другое решение с data.table :

R> DT <- data.table(IN)
R> DT[,RESULT:=ifelse(.N>1,"y","n"), by=list(DATE,TRAP)]
R> DT
   ID       DATE TRAP RESULT
1:  1 2013-01-01    1      y
2:  2 2013-01-01    1      y
3:  3 2013-01-01    1      y
4:  1 2013-01-02    3      y
5:  2 2013-01-01    2      n
6:  3 2013-01-02    3      y
7:  1 2013-01-03    2      n
8:  2 2013-01-03    1      n
9:  3 2013-01-03    3      n

Здесь нет переупорядочивания.


Или используя базу ave:

IN <- within(IN, { RESULT <- ave(TRAP, list(DATE, TRAP), 
               FUN= function(x) ifelse(length(x) > 1, "y", "n"))})
#   ID       DATE TRAP RESULT
# 1  1 2013-01-01    1      y
# 2  2 2013-01-01    1      y
# 3  3 2013-01-01    1      y
# 4  1 2013-01-02    3      y
# 5  2 2013-01-01    2      n
# 6  3 2013-01-02    3      y
# 7  1 2013-01-03    2      n
# 8  2 2013-01-03    1      n
# 9  3 2013-01-03    3      n
person juba    schedule 22.04.2013
comment
Большое спасибо @juba за предложение. Я не знал пакет plyr, действительно полезный! Еще раз, я ценю! - person stefano; 22.04.2013
comment
Привет @Arun, я думал, что ave может быть полезен для этого вопроса (поскольку вы уже помогли мне с этой функцией!) ... большое спасибо! - person stefano; 22.04.2013
comment
@Arun спасибо за базовое решение и правку. Вы могли бы опубликовать другой ответ, потому что я не могу сейчас проголосовать за вас :) - person juba; 22.04.2013
comment
stefano, это очень удобная функция, которую часто недооценивают. У меня есть миссия изменить это :P. @juba, лучше иметь все в одном месте. Вы должны мне 1 голос вверх! :П - person Arun; 22.04.2013

Вы можете использовать duplicated для этого:

IN$RESULT <- ifelse((duplicated(IN[,2:3])+duplicated(IN[,2:3],fromLast=TRUE))>0,
                       "y","n")

#   ID       DATE TRAP RESULT
# 1  1 2013-01-01    1      y
# 2  2 2013-01-01    1      y
# 3  3 2013-01-01    1      y
# 4  1 2013-01-02    3      y
# 5  2 2013-01-01    2      n
# 6  3 2013-01-02    3      y
# 7  1 2013-01-03    2      n
# 8  2 2013-01-03    1      n
# 9  3 2013-01-03    3      n
person Roland    schedule 22.04.2013
comment
хорошо знать эту другую полезную функцию! Я ценю вашу помощь. - person stefano; 23.04.2013