2013-12-08 5 views
3

Моего Отправное состояния что-то вроде рамки df данныхУсловное создание колонки (горизонтальные и вертикальные условия)

df<-data.frame(id=c(rep(2, 3), rep(4, 2)), year=c(2005:2007, 2005:2006), event=c(1,0,0,0,1)) 

    id year event 
1 2 2005  1 
2 2 2006  0 
3 2 2007  0 
4 4 2005  0 
5 4 2006  1 

У меня есть ряд актеров (идентифицированных через ид), которые происходят испытать событие в определенном год.

Здесь я пытаюсь построить ряд дополнительных столбцов, которые описывают а) расстояние от событий и б) является ли такое расстояние наблюдаемым.

Это то, что я хотел бы получить.

id year event evm2 evm1 evp1 evp2 ndm2 ndm1 ndp1 ndp2 
1 2 2005  1 0 0 0 0 1 1 0 0 
2 2 2006  0 0 1 0 0 1 0 0 1 
3 2 2007  0 1 0 0 0 0 0 1 1 
4 4 2005  0 0 0 1 0 1 1 0 1 
5 4 2006  1 0 0 0 0 1 0 1 1 

event равен 1, когда происходит событие в определенном году. evm1 равно 1, когда событие можно наблюдать за год до этого. Аналогично, evp1 равно 1, если событие находится в следующем году - буквы p или m подставка для «плюс» и «минус», а цифры представляют собой расстояние в годах от события. Для некоторых из этих наблюдений расстояние не наблюдается, поскольку доступное временное окно слишком короткое. Это относится к df[1,], для которого мы не знаем, произошло ли в предыдущие годы событие или нет. В таком случае, ndm1 и ndm2 кодируются 1. Если мы рассмотрим случай df[5,], это будет ndp1ndp2) должны быть закодированы 1. ev и nd переменных работают точно таким же образом. Но первый говорит, что на определенном расстоянии есть какое-то событие или нет, и последнее показывает, действительно ли такое расстояние действительно наблюдаемо.

Я попытался выполнить это, используя следующие вложенные петли, но мне это не удалось.

lag<-c(-2, -1, 1, 2) 
df2<-df 
df2[,4:11]<-0 
colnames(df2)<-c("id", "year", "event", "evm2", "evm1", "evp1", "evp2", "ndm2", "ndm1", "ndp1", "ndp2") 


for (i in length(df2$id)) { 

    id<-df2[i,1] 
    yr<-df2[i,2] 
    sta<-3 
    sta2<-7 

    for (j in lag){ 

    sta<-sta+1 
    sta2<-sta2+1 

    if !is.null(df2[df2$id==id & df2$year==yr+j])==TRUE { 

     rw<-which(df2[df2$id==id & df2$year==yr+j]) 

     if (df2[rw,3]==1) df2[i, sta]==1 

    } else { 

     df2[i, sta2]==1 

    } 

    } 

} 

Вы видите что-нибудь, что может быть причиной ошибок? Я два дня схожу с ума, пытаясь заставить его работать, и я был бы очень благодарен, если бы вы могли помочь.

+0

Отсутствуют скобки вокруг условия 'if' - это первое. И вам не нужно проверять равенство с «ИСТИНА». Это должно быть: 'if (! Is.null (df2 [df2 $ id == id & df2 $ year == yr + j]))' Однако я не уверен, что это единственная проблема. –

+0

Можно ли предположить, что для данного 'id', у вас всегда есть данные для набора не менее двух непрерывных и отсортированных лет? Если это так, я могу показать короткое и векторизованное решение. – flodel

+0

@musically_ut Большое спасибо за ваш комментарий. Вы совершенно правы. То, что все еще не работает, это то, что функция. У вас есть идея, почему? – Riccardo

ответ

3

После моего комментария, вот что я имел в виду в качестве потенциального переписывания:

lag.it <- function(x, n = 0L) { 
    l <- length(x) 
    neg.lag <- min(max(0L, -n), l) 
    pos.lag <- min(max(0L, +n), l) 
    c(rep(NA, +neg.lag), 
    head(x, -neg.lag), 
    tail(x, -pos.lag), 
    rep(NA, +pos.lag)) 
} 

library(plyr) 
ddply(df, "id", transform, 
     evm2 = lag.it(event, -2), 
     evm1 = lag.it(event, -1), 
     evp1 = lag.it(event, +1), 
     evp2 = lag.it(event, +2)) 

# id year event evm2 evm1 evp1 evp2 
# 1 2 2005  1 NA NA 0 0 
# 2 2 2006  0 NA 1 0 NA 
# 3 2 2007  0 1 0 NA NA 
# 4 4 2005  0 NA NA 1 NA 
# 5 4 2006  1 NA 0 NA NA 

Обратите внимание, как я использую NA с вместо того, чтобы использовать два набора переменных. Хотя я бы порекомендовал вам сохранить его таким образом, вы можете легко получить то, что попросили, указав, например, ndm2, как is.na(evm2), затем замените NA с нулями.

+0

Я действительно считаю, что это решение гениально. Это настолько умно, что я, вероятно, не понимаю его полностью (в частности, я не понимаю определения neg.lag и pos.lag). Не могли бы вы объяснить это мне? Чтобы ответить на ваш вопрос выше, некоторые наблюдения, которые я наблюдаю, наблюдаются в течение 7 лет, в то время как другие только за более короткое время - некоторые из них только на 1 год. В любом случае, я буду рассматривать отставание +/- 2 года для создания дополнительных переменных. Ваша помощь очень ценится. – Riccardo

+1

В зависимости от знака (положительного или отрицательного) лага 'n' вам нужно добавить (положительное число)' NA' в начале или в конце вашего вектора. Вот почему я полагаюсь на две переменные «neg.lag» и «pos.lag», но по определению только один из двух будет отличным от нуля. Рад, что вам понравилось это решение. Если он решает вашу проблему, пожалуйста, подумайте о том, чтобы продолжить и принять его. – flodel

+0

Решение принято. Я уже поддержал. Мне до сих пор неясна очень маленькая деталь. Почему вы пишете 0L вместо того, чтобы просто писать 0? Еще раз спасибо. Отличный урок стиля кодирования R. – Riccardo

Смежные вопросы