Условие ifelse для расчета на нескольких фреймах данных - PullRequest
0 голосов
/ 28 июня 2018

У меня есть 3 фрейма данных, df1 = интервал времени, df2 = список идентификаторов, df3 = список идентификаторов с соответствующей датой.

df1 <- structure(list(season = structure(c(2L, 1L), .Label = c("summer", 
    "winter"), class = "factor"), mindate = structure(c(1420088400, 
    1433131200), class = c("POSIXct", "POSIXt")), maxdate = structure(c(1433131140, 
    1448945940), class = c("POSIXct", "POSIXt")), diff = structure(c(150.957638888889, 
    183.040972222222), units = "days", class = "difftime")), .Names = c("season", 
    "mindate", "maxdate", "diff"), row.names = c(NA, -2L), class = "data.frame")

df2 <- structure(list(ID = c(23796, 23796, 23796)), .Names = "ID", row.names = c(NA, 
    -3L), class = "data.frame")

df3 <- structure(list(ID = c("23796", "123456", "12134"), time = structure(c(1420909920, 
1444504500, 1444504500), class = c("POSIXct", "POSIXt"), tzone = "US/Eastern")), .Names = c("ID", 
"time"), row.names = c(NA, -3L), class = "data.frame")

Код должен сравниваться, если df2 $ ID == df3 $ ID. Если true, и если df3 $ time> = df1 $ mindate и df3 $ time <= df1 $ maxdate, то df1 $ maxdate - df3 $ time, иначе df1 $ maxdate - df1 $ mindate. Я пытался использовать функцию ifelse. Это работает, когда я вручную указываю конкретные ячейки, но это не то, что я хочу, так как у меня есть еще много (неровных строк) для каждого из dfs. </p>

df1$result <- ifelse(df2[1,1] == df3[1,1] & df3[1,2] >= df1$mindate & df3[1,2] <= df1$maxdate, 
                     difftime(df1$maxdate,df3[1,2],units="days"),
                     difftime(df1$maxdate,df1$mindate,units="days")

EDIT: желаемый результат (при удалении последней строки df2):

 season    mindate             maxdate          diff   result
1 winter 2015-01-01 2015-05-31 23:59:00 150.9576 days 141.9576
2 summer 2015-06-01 2015-11-30 23:59:00 183.0410 days 183.0410

Есть идеи? Я не понимаю, как я мог бы объединить DFS, чтобы сделать их одинаковой длины. Обратите внимание, что df2 может иметь любую длину строки и не влиять на код. Проблемы возникают, когда df1 и df3 отличаются количеством строк.

1 Ответ

0 голосов
/ 28 июня 2018

> и < векторизованы:

transform(df1,result=ifelse(df3$ID%in%df2$ID & df3$time>mindate & df3$time <maxdate, difftime(maxdate,df3$time),difftime(maxdate,mindate)))
  season             mindate             maxdate          diff   result
1 winter 2014-12-31 21:00:00 2015-05-31 20:59:00 150.9576 days 141.9576
2 summer 2015-05-31 21:00:00 2015-11-30 20:59:00 183.0410 days 183.0410

Вы также можете использовать функцию between из data.table библиотеки

library(data.table)
transform(df1,result=ifelse(df3$ID%in%df2$ID&df3$time%between%df1[2:3],
               difftime(maxdate,df3$time),difftime(maxdate,mindate)))

  season             mindate             maxdate          diff   result
1 winter 2014-12-31 21:00:00 2015-05-31 20:59:00 150.9576 days 141.9576
2 summer 2015-05-31 21:00:00 2015-11-30 20:59:00 183.0410 days 183.0410
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...