zona mundial meridiano mapa husos horarios horaria hora greenwich exacta ejemplos conversor r match apply

mundial - Hacer coincidir los datos con marca de tiempo con la hora más cercana en otro conjunto de datos. ¿Está correctamente vectorizado? ¿De manera más rápida?



meridiano de greenwich hora (2)

Tengo una marca de tiempo en un marco de datos que trato de hacer coincidir con la marca de tiempo más cercana en un segundo marco de datos, con el propósito de extraer datos del segundo marco de datos. Vea a continuación un ejemplo genérico de mi enfoque:

library(lubridate) data <- data.frame(datetime=ymd_hms(c(''2015-04-01 12:23:00 UTC'', ''2015-04-01 13:49:00 UTC'', ''2015-04-01 14:06:00 UTC'' ,''2015-04-01 14:49:00 UTC'')), value=c(1,2,3,4)) reference <- data.frame(datetime=ymd_hms(c(''2015-04-01 12:00:00 UTC'', ''2015-04-01 13:00:00 UTC'', ''2015-04-01 14:00:00 UTC'' ,''2015-04-01 15:00:00 UTC'', ''2015-04-01 16:00:00 UTC'')), refvalue=c(5,6,7,8,9)) data$refvalue <- apply(data, 1, function (x){ differences <- abs(as.numeric(difftime(ymd_hms(x[''datetime'']), reference$datetime))) mindiff <- min(differences) return(reference$refvalue[differences == mindiff]) }) data # datetime value refvalue # 1 2015-04-01 12:23:00 1 5 # 2 2015-04-01 13:49:00 2 7 # 3 2015-04-01 14:06:00 3 7 # 4 2015-04-01 14:49:00 4 8

Esto funciona bien, excepto que es muy lento, porque el marco de datos de referencia es bastante grande en mi aplicación del mundo real. ¿Este código está correctamente vectorizado? ¿Hay una forma más rápida y elegante de realizar esta operación?


Me pregunté si esto podría coincidir con una solución de velocidad de tabla de datos, pero es una solución vectorizada de base-R que debería superar a su versión de apply . Y como en realidad nunca calcula una distancia, en realidad podría ser más rápido que el enfoque de datos más cercano. Esto agrega la longitud de los puntos medios de los intervalos al valor más bajo posible o al punto de inicio de los intervalos para crear un conjunto de "interrupciones intermedias" y luego utiliza la función findInterval para procesar los tiempos. Eso crea un índice adecuado en las filas del conjunto de datos de reference y el "valor de referencia" se puede "transferir" al objeto de data .

data$reefvalue <- reference$refvalue[ findInterval( data$datetime, c(-Inf, head(reference$datetime,-1))+ c(0, diff(as.numeric(reference$datetime))/2 )) ] # values are [1] 5 7 7 8


Puedes probar data.table s rolling join usando la opción "más cercana"

library(data.table) # v1.9.6+ setDT(reference)[data, refvalue, roll = "nearest", on = "datetime"] # [1] 5 7 7 8