I have created two sf
objects, one for animal locations, and one for turbine locations. The Turbine_sf
includes construction start and stop dates, along with operation dates for each structure.
What I am attempting to do is filter turbine construction/operation dates based on each animal's timestamps (DateTime
in pronghorn_sf
. I wouldd like to measure the distance to the nearest turbine under construction for each animal location in pronghorn_sf
.
I have included my attempt below, which seems to only measure distance for odd numbered rows (cp. picture), rather than date matching animal timestamps and turbine construction periods.
Attempt
# ensure the sf objects are using the same crs
pronghorn_sf <- st_transform(pronghorn_sf, st_crs(Turbine_sf))
# create distance columns using a vectorized approach
pronghorn_sf$construction_distance1 <- apply(st_coordinates(pronghorn_sf), 1, function(coords) {
current_date <- pronghorn_sf$DateTime[which(st_coordinates(pronghorn_sf) == coords)]
# filter turbines under construction during a pronghorn location's timestamp
turbines_under_construction <- Turbine_sf %>%
filter(current_date >= Phase1_Construction_Start_Date & current_date <= Phase1_Construction_End_Date)
if (nrow(turbines_under_construction) > 0) {
# calculate the distance only if relevant turbines exist
min(st_distance(st_sfc(st_point(coords), crs = st_crs(Turbine_sf)), turbines_under_construction))
} else {
NA
}
})
which gives
Data
- 25 rows of
pronghorn_sf
:
> dput(pronghorn_sf1)
structure(list(AID = structure(c(137L, 137L, 137L, 137L, 137L,
137L, 137L, 137L, 137L, 137L, 137L, 137L, 137L, 137L, 137L, 139L,
139L, 139L, 139L, 139L, 139L, 139L, 139L, 139L, 139L), levels = c("BH_002",
"BH_003", "BH_004", "BH_005", "BH_006", "BH_007", "BH_008", "BH_009",
"BH_010", "BH_011", "BH_012", "BH_013", "BH_014", "BH_015", "BH_016",
"BH_017", "BH_019", "BH_020", "BH_021", "BH_022", "BH_024", "BH_025",
"BH_026", "BH_028", "BH_029", "BH_030", "BH_031", "BH_033", "BH_035",
"BH_036", "BH_037", "BH_038", "BH_039", "BH_040", "BH_041", "BH_042",
"BH_043", "BH_044", "BH_046", "BH_047", "BH_048", "BH_049", "BH_051",
"BH_052", "BH_053", "BH_054", "BH_055", "BH_056", "BH_057", "BH_058",
"SB_001", "SB_002", "SB_004", "SB_006", "SB_007", "SB_008", "SB_009",
"SB_010", "SB_011", "SB_012", "SB_014", "SB_015", "SB_016", "SB_017",
"SB_018", "SB_019", "SB_020", "SB_021", "SB_022", "SB_024", "SB_025",
"SB_028", "SB_029", "SB_031", "SB_032", "SB_033", "SB_034", "SB_035",
"SB_036", "SB_037", "SB_038", "SB_039", "SB_040", "SB_041", "SB_043",
"SB_044", "SB_045", "SB_046", "SB_047", "SB_049", "SB_052", "SB_053",
"SB_054", "SB_055", "SB_056", "SB_057", "SB_058", "SB_059", "SB_060",
"SB_061", "SB_062", "SB_063", "SB_064", "SB_065", "SB_067", "SB_068",
"SB_069", "SB_070", "SB_071", "SB_072", "SB_074", "SB_075", "SB_076",
"SB_077", "SB_078", "SB_079", "SB_080", "SB_081", "SB_083", "SB_084",
"SB_085", "SB_086", "SB_087", "SB_088", "SB_089", "SB_090", "SB_091",
"SB_092", "SB_093", "SB_094", "SB_095", "SB_096", "SB_097", "SB_098",
"SB_099", "SB_100", "SB_101", "SB_102", "SB_103", "SB_104", "SB_105",
"SB_106", "SB_108", "SB_109", "SB_110", "SB_111", "SB_112", "SB_113",
"SB_114", "SB_115", "SB_116", "SB_117", "SB_118", "SB_119", "SB_120",
"SB_121", "SB_122", "SB_123", "SB_124", "SB_125", "SB_126", "SB_127",
"SB_128", "SB_130", "SB_131", "SB_132", "SB_133", "SB_134", "SB_136",
"SB_137", "SB_138", "SB_139", "SB_140", "SB_141", "SB_143", "SB_146",
"SB_147", "SB_148", "SB_150", "SB_152", "SB_153", "SB_154", "SB_155",
"SB_156", "SB_157", "SB_158", "SB_159", "SB_160", "SB_161", "SB_162",
"SB_163", "SB_165", "SB_166", "SB_167", "SB_168", "SB_169", "SB_171",
"SB_172", "SB_174", "SB_175", "SB_176", "SB_180", "SB_181", "SB_182",
"SB_183", "SB_184", "SB_185", "SB_186", "SB_187", "SB_188", "SB_189",
"SB_190", "SB_191", "SB_192", "SB_193", "SB_194", "SB_195", "SB_196",
"SB_202", "SB_205", "SB_210", "SB_211", "SB_212", "SB_213", "SB_214",
"SB_215", "SB_216", "SB_217", "SB_218", "SB_219", "SB_220", "SB_221",
"SB_222", "SB_223", "SB_224", "SB_225", "SB_226", "SB_227", "SB_228",
"SB_230", "SB_231", "SB_232", "SB_233", "SB_234", "SB_235", "SB_236",
"SB_237", "SB_238", "SB_240", "SB_241", "SB_243", "SB_244", "SB_245",
"SB_246", "SB_247", "SB_248"), class = "factor"), DateTime = structure(c(1671854437,
1671868837, 1671883237, 1671897642, 1671912037, 1671926437, 1671940837,
1671955242, 1671969644, 1671984058, 1671998437, 1672012837, 1672027237,
1672041646, 1672056037, 1567447242, 1567454404, 1567461604, 1567468803,
1567476091, 1567483204, 1567490404, 1567497609, 1567612804, 1567620058
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), YNorthing = c(4640831.29,
4640687.169, 4642397.708, 4644840.306, 4646350.756, 4646919.927,
4646534.687, 4646865.79, 4647306.727, 4647076.159, 4649330.737,
4649855.958, 4649766.786, 4650129.319, 4650288.699, 4650026,
4649935, 4650148, 4650218, 4650226, 4650345, 4650342, 4650351,
4650040, 4649923), XEasting = c(13424219.597, 13425259.957, 13417594.318,
13415562.718, 13416285.702, 13415025.005, 13414998.247, 13415298.28,
13415021.033, 13416268.994, 13416506.255, 13416930.762, 13417068.436,
13417213.538, 13416885.97, 429788, 429323, 429119, 429078, 428974,
428886, 428883, 429023, 429870, 429600), x = c(424219.594584907,
425259.960358151, 417594.314800596, 415562.71890358, 416285.698693028,
415025.006157442, 414998.250352198, 415298.279154033, 415021.035323201,
416268.994737265, 416506.253844386, 416930.762803482, 417068.435627463,
417213.538974703, 416885.968245001, 429788.134621699, 429322.978335433,
429118.858664836, 429078.310284856, 428973.536615617, 428885.689295124,
428882.513327488, 429023.407508244, 429870.020439793, 429599.915982921
), y = c(4640831.28886158, 4640687.163379, 4642397.70379822,
4644840.30088953, 4646350.75440094, 4646919.92935201, 4646534.68665156,
4646865.79303352, 4647306.72834182, 4647076.15648437, 4649330.73207423,
4649855.95795628, 4649766.78705397, 4650129.32171694, 4650288.69561457,
4650026.21325154, 4649935.33876174, 4650147.91029761, 4650217.82758664,
4650226.20503632, 4650344.90043192, 4650342.04521013, 4650351.29340809,
4650039.8382759, 4649922.70138309), geometry = structure(list(
structure(c(-105.9138196, 41.9157991), class = c("XY", "POINT",
"sfg")), structure(c(-105.9012573, 41.9146003), class = c("XY",
"POINT", "sfg")), structure(c(-105.9939202, 41.9292418), class = c("XY",
"POINT", "sfg")), structure(c(-106.0187703, 41.9510235), class = c("XY",
"POINT", "sfg")), structure(c(-106.0102634, 41.9647027), class = c("XY",
"POINT", "sfg")), structure(c(-106.0255573, 41.9696934), class = c("XY",
"POINT", "sfg")), structure(c(-106.0258245, 41.9662213), class = c("XY",
"POINT", "sfg")), structure(c(-106.0222519, 41.9692353), class = c("XY",
"POINT", "sfg")), structure(c(-106.0256611, 41.9731762), class = c("XY",
"POINT", "sfg")), structure(c(-106.0105682, 41.9712334), class = c("XY",
"POINT", "sfg")), structure(c(-106.0080253, 41.9915617), class = c("XY",
"POINT", "sfg")), structure(c(-106.0029752, 41.9963364), class = c("XY",
"POINT", "sfg")), structure(c(-106.0013006, 41.9955479), class = c("XY",
"POINT", "sfg")), structure(c(-105.9996, 41.9988279), class = c("XY",
"POINT", "sfg")), structure(c(-106.0035772, 42.0002286), class = c("XY",
"POINT", "sfg")), structure(c(-105.847774, 41.999121), class = c("XY",
"POINT", "sfg")), structure(c(-105.853379, 41.998261), class = c("XY",
"POINT", "sfg")), structure(c(-105.855869, 42.000157), class = c("XY",
"POINT", "sfg")), structure(c(-105.856367, 42.000783), class = c("XY",
"POINT", "sfg")), structure(c(-105.857633, 42.000849), class = c("XY",
"POINT", "sfg")), structure(c(-105.858708, 42.00191), class = c("XY",
"POINT", "sfg")), structure(c(-105.858746, 42.001884), class = c("XY",
"POINT", "sfg")), structure(c(-105.857046, 42.00198), class = c("XY",
"POINT", "sfg")), structure(c(-105.846787, 41.999251), class = c("XY",
"POINT", "sfg")), structure(c(-105.850034, 41.998172), class = c("XY",
"POINT", "sfg"))), class = c("sfc_POINT", "sfc"), precision = 0, bbox = structure(c(xmin = -106.0258245,
ymin = 41.9146003, xmax = -105.846787, ymax = 42.00198), class = "bbox"), crs = structure(list(
input = "EPSG:4326", wkt = "GEOGCRS[\"WGS 84\",\n ENSEMBLE[\"World Geodetic System 1984 ensemble\",\n MEMBER[\"World Geodetic System 1984 (Transit)\"],\n MEMBER[\"World Geodetic System 1984 (G730)\"],\n MEMBER[\"World Geodetic System 1984 (G873)\"],\n MEMBER[\"World Geodetic System 1984 (G1150)\"],\n MEMBER[\"World Geodetic System 1984 (G1674)\"],\n MEMBER[\"World Geodetic System 1984 (G1762)\"],\n MEMBER[\"World Geodetic System 1984 (G2139)\"],\n ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n LENGTHUNIT[\"metre\",1]],\n ENSEMBLEACCURACY[2.0]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n CS[ellipsoidal,2],\n AXIS[\"geodetic latitude (Lat)\",north,\n ORDER[1],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n AXIS[\"geodetic longitude (Lon)\",east,\n ORDER[2],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n USAGE[\n SCOPE[\"Horizontal component of 3D system.\"],\n AREA[\"World.\"],\n BBOX[-90,-180,90,180]],\n ID[\"EPSG\",4326]]"), class = "crs"), n_empty = 0L)), sf_column = "geometry", agr = structure(c(AID = 1L,
DateTime = 1L, YNorthing = 1L, XEasting = 1L, x = 1L, y = 1L), levels = c("constant",
"aggregate", "identity"), class = "factor"), row.names = 145350:145374, class = c("sf",
"data.frame"))
- 50 rows of
Turbine_sf1
:
> dput(Turbine_sf1)
structure(list(name = c("Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Ekola Flats",
"Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats",
"Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats",
"Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats",
"Ekola Flats"), pronghorn_overlap = c("Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes"), Phase1_Construction_Start_Date = structure(c(13977,
13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977,
13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977,
13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977,
13977, 13977, 13977, 13977, 13977, 13977, 18044, 18044, 18044,
18044, 18044, 18044, 18044, 18044, 18044, 18044, 18044, 18044,
18044, 18044, 18044, 18044, 18044), class = "Date"), Phase1_Construction_End_Date = structure(c(14183,
14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183,
14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183,
14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183,
14183, 14183, 14183, 14183, 14183, 14183, 18261, 18261, 18261,
18261, 18261, 18261, 18261, 18261, 18261, 18261, 18261, 18261,
18261, 18261, 18261, 18261, 18261), class = "Date"), Phase2_Construction_Start_Date = structure(c(NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, 18322, 18322, 18322, 18322, 18322, 18322, 18322, 18322, 18322,
18322, 18322, 18322, 18322, 18322, 18322, 18322, 18322), class = "Date"),
Phase2_Construction_End_Date = structure(c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
18551, 18551, 18551, 18551, 18551, 18551, 18551, 18551, 18551,
18551, 18551, 18551, 18551, 18551, 18551, 18551, 18551), class = "Date"),
Phase3_Construction_Start_Date = structure(c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_), class = "Date"), Phase3_Construction_End_Date = structure(c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_), class = "Date"), Operation_Date = structure(c(14232,
14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232,
14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232,
14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232,
14232, 14232, 14232, 14232, 14232, 14232, 18611, 18611, 18611,
18611, 18611, 18611, 18611, 18611, 18611, 18611, 18611, 18611,
18611, 18611, 18611, 18611, 18611), class = "Date"), Operation_End_Date = structure(c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_), class = "Date"), Second_Operation_Start_Date = structure(c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_), class = "Date"), Second_Operation_End_Date = structure(c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_), class = "Date"), geometry = structure(list(
structure(c(-106.38279, 41.957691), class = c("XY", "POINT",
"sfg")), structure(c(-106.434891, 41.971191), class = c("XY",
"POINT", "sfg")), structure(c(-106.411491, 41.946693), class = c("XY",
"POINT", "sfg")), structure(c(-106.37899, 41.919693), class = c("XY",
"POINT", "sfg")), structure(c(-106.365585, 41.945694), class = c("XY",
"POINT", "sfg")), structure(c(-106.43399, 41.969692), class = c("XY",
"POINT", "sfg")), structure(c(-106.426491, 41.957592), class = c("XY",
"POINT", "sfg")), structure(c(-106.412491, 41.959293), class = c("XY",
"POINT", "sfg")), structure(c(-106.411591, 41.948292), class = c("XY",
"POINT", "sfg")), structure(c(-106.372787, 41.940292), class = c("XY",
"POINT", "sfg")), structure(c(-106.366089, 41.926693), class = c("XY",
"POINT", "sfg")), structure(c(-106.41259, 41.943092), class = c("XY",
"POINT", "sfg")), structure(c(-106.377586, 41.917091), class = c("XY",
"POINT", "sfg")), structure(c(-106.412888, 41.956093), class = c("XY",
"POINT", "sfg")), structure(c(-106.383286, 41.950592), class = c("XY",
"POINT", "sfg")), structure(c(-106.366592, 41.921993), class = c("XY",
"POINT", "sfg")), structure(c(-106.36599, 41.928093), class = c("XY",
"POINT", "sfg")), structure(c(-106.411987, 41.957592), class = c("XY",
"POINT", "sfg")), structure(c(-106.425591, 41.962013), class = c("XY",
"POINT", "sfg")), structure(c(-106.411888, 41.952991), class = c("XY",
"POINT", "sfg")), structure(c(-106.366089, 41.923393), class = c("XY",
"POINT", "sfg")), structure(c(-106.365585, 41.952194), class = c("XY",
"POINT", "sfg")), structure(c(-106.425591, 41.959091), class = c("XY",
"POINT", "sfg")), structure(c(-106.435486, 41.962193), class = c("XY",
"POINT", "sfg")), structure(c(-106.372787, 41.936092), class = c("XY",
"POINT", "sfg")), structure(c(-106.420792, 41.971294), class = c("XY",
"POINT", "sfg")), structure(c(-106.372787, 41.938892), class = c("XY",
"POINT", "sfg")), structure(c(-106.383392, 41.947693), class = c("XY",
"POINT", "sfg")), structure(c(-106.383369, 41.949146), class = c("XY",
"POINT", "sfg")), structure(c(-106.366692, 41.916294), class = c("XY",
"POINT", "sfg")), structure(c(-106.382187, 41.927792), class = c("XY",
"POINT", "sfg")), structure(c(-106.43399, 41.968094), class = c("XY",
"POINT", "sfg")), structure(c(-106.411789, 41.945091), class = c("XY",
"POINT", "sfg")), structure(c(-106.366287, 41.956993), class = c("XY",
"POINT", "sfg")), structure(c(-106.202492, 41.625603), class = c("XY",
"POINT", "sfg")), structure(c(-106.19799, 41.642895), class = c("XY",
"POINT", "sfg")), structure(c(-106.291626, 41.913994), class = c("XY",
"POINT", "sfg")), structure(c(-106.196388, 41.645935), class = c("XY",
"POINT", "sfg")), structure(c(-106.209488, 41.611423), class = c("XY",
"POINT", "sfg")), structure(c(-106.202187, 41.628925), class = c("XY",
"POINT", "sfg")), structure(c(-106.201286, 41.636032), class = c("XY",
"POINT", "sfg")), structure(c(-106.278893, 41.941605), class = c("XY",
"POINT", "sfg")), structure(c(-106.355293, 41.963017), class = c("XY",
"POINT", "sfg")), structure(c(-106.328705, 41.919952), class = c("XY",
"POINT", "sfg")), structure(c(-106.341125, 41.919991), class = c("XY",
"POINT", "sfg")), structure(c(-106.205193, 41.618633), class = c("XY",
"POINT", "sfg")), structure(c(-106.328712, 41.923618), class = c("XY",
"POINT", "sfg")), structure(c(-106.250381, 41.917053), class = c("XY",
"POINT", "sfg")), structure(c(-106.253632, 41.919395), class = c("XY",
"POINT", "sfg")), structure(c(-106.341705, 41.923336), class = c("XY",
"POINT", "sfg")), structure(c(-106.207588, 41.615055), class = c("XY",
"POINT", "sfg"))), class = c("sfc_POINT", "sfc"), precision = 0, bbox = structure(c(xmin = -106.435486,
ymin = 41.611423, xmax = -106.196388, ymax = 41.971294), class = "bbox"), crs = structure(list(
input = "EPSG:4326", wkt = "GEOGCRS[\"WGS 84\",\n ENSEMBLE[\"World Geodetic System 1984 ensemble\",\n MEMBER[\"World Geodetic System 1984 (Transit)\"],\n MEMBER[\"World Geodetic System 1984 (G730)\"],\n MEMBER[\"World Geodetic System 1984 (G873)\"],\n MEMBER[\"World Geodetic System 1984 (G1150)\"],\n MEMBER[\"World Geodetic System 1984 (G1674)\"],\n MEMBER[\"World Geodetic System 1984 (G1762)\"],\n MEMBER[\"World Geodetic System 1984 (G2139)\"],\n ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n LENGTHUNIT[\"metre\",1]],\n ENSEMBLEACCURACY[2.0]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n CS[ellipsoidal,2],\n AXIS[\"geodetic latitude (Lat)\",north,\n ORDER[1],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n AXIS[\"geodetic longitude (Lon)\",east,\n ORDER[2],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n USAGE[\n SCOPE[\"Horizontal component of 3D system.\"],\n AREA[\"World.\"],\n BBOX[-90,-180,90,180]],\n ID[\"EPSG\",4326]]"), class = "crs"), n_empty = 0L)), sf_column = "geometry", agr = structure(c(name = 1L,
pronghorn_overlap = 1L, Phase1_Construction_Start_Date = 1L,
Phase1_Construction_End_Date = 1L, Phase2_Construction_Start_Date = 1L,
Phase2_Construction_End_Date = 1L, Phase3_Construction_Start_Date = 1L,
Phase3_Construction_End_Date = 1L, Operation_Date = 1L, Operation_End_Date = 1L,
Second_Operation_Start_Date = 1L, Second_Operation_End_Date = 1L
), levels = c("constant", "aggregate", "identity"), class = "factor"), row.names = 225:275, class = c("sf",
"data.frame"))
I'd like to end up with a new column in the pronghorn_sf object (which I will probably convert to a dataframe or datatable) that includes distance in meters to the nearest turbine under construction. If an animal's timestamp falls outside of turbine construction periods, I'd like to populate those rows with NAs.
I have created two sf
objects, one for animal locations, and one for turbine locations. The Turbine_sf
includes construction start and stop dates, along with operation dates for each structure.
What I am attempting to do is filter turbine construction/operation dates based on each animal's timestamps (DateTime
in pronghorn_sf
. I wouldd like to measure the distance to the nearest turbine under construction for each animal location in pronghorn_sf
.
I have included my attempt below, which seems to only measure distance for odd numbered rows (cp. picture), rather than date matching animal timestamps and turbine construction periods.
Attempt
# ensure the sf objects are using the same crs
pronghorn_sf <- st_transform(pronghorn_sf, st_crs(Turbine_sf))
# create distance columns using a vectorized approach
pronghorn_sf$construction_distance1 <- apply(st_coordinates(pronghorn_sf), 1, function(coords) {
current_date <- pronghorn_sf$DateTime[which(st_coordinates(pronghorn_sf) == coords)]
# filter turbines under construction during a pronghorn location's timestamp
turbines_under_construction <- Turbine_sf %>%
filter(current_date >= Phase1_Construction_Start_Date & current_date <= Phase1_Construction_End_Date)
if (nrow(turbines_under_construction) > 0) {
# calculate the distance only if relevant turbines exist
min(st_distance(st_sfc(st_point(coords), crs = st_crs(Turbine_sf)), turbines_under_construction))
} else {
NA
}
})
which gives
Data
- 25 rows of
pronghorn_sf
:
> dput(pronghorn_sf1)
structure(list(AID = structure(c(137L, 137L, 137L, 137L, 137L,
137L, 137L, 137L, 137L, 137L, 137L, 137L, 137L, 137L, 137L, 139L,
139L, 139L, 139L, 139L, 139L, 139L, 139L, 139L, 139L), levels = c("BH_002",
"BH_003", "BH_004", "BH_005", "BH_006", "BH_007", "BH_008", "BH_009",
"BH_010", "BH_011", "BH_012", "BH_013", "BH_014", "BH_015", "BH_016",
"BH_017", "BH_019", "BH_020", "BH_021", "BH_022", "BH_024", "BH_025",
"BH_026", "BH_028", "BH_029", "BH_030", "BH_031", "BH_033", "BH_035",
"BH_036", "BH_037", "BH_038", "BH_039", "BH_040", "BH_041", "BH_042",
"BH_043", "BH_044", "BH_046", "BH_047", "BH_048", "BH_049", "BH_051",
"BH_052", "BH_053", "BH_054", "BH_055", "BH_056", "BH_057", "BH_058",
"SB_001", "SB_002", "SB_004", "SB_006", "SB_007", "SB_008", "SB_009",
"SB_010", "SB_011", "SB_012", "SB_014", "SB_015", "SB_016", "SB_017",
"SB_018", "SB_019", "SB_020", "SB_021", "SB_022", "SB_024", "SB_025",
"SB_028", "SB_029", "SB_031", "SB_032", "SB_033", "SB_034", "SB_035",
"SB_036", "SB_037", "SB_038", "SB_039", "SB_040", "SB_041", "SB_043",
"SB_044", "SB_045", "SB_046", "SB_047", "SB_049", "SB_052", "SB_053",
"SB_054", "SB_055", "SB_056", "SB_057", "SB_058", "SB_059", "SB_060",
"SB_061", "SB_062", "SB_063", "SB_064", "SB_065", "SB_067", "SB_068",
"SB_069", "SB_070", "SB_071", "SB_072", "SB_074", "SB_075", "SB_076",
"SB_077", "SB_078", "SB_079", "SB_080", "SB_081", "SB_083", "SB_084",
"SB_085", "SB_086", "SB_087", "SB_088", "SB_089", "SB_090", "SB_091",
"SB_092", "SB_093", "SB_094", "SB_095", "SB_096", "SB_097", "SB_098",
"SB_099", "SB_100", "SB_101", "SB_102", "SB_103", "SB_104", "SB_105",
"SB_106", "SB_108", "SB_109", "SB_110", "SB_111", "SB_112", "SB_113",
"SB_114", "SB_115", "SB_116", "SB_117", "SB_118", "SB_119", "SB_120",
"SB_121", "SB_122", "SB_123", "SB_124", "SB_125", "SB_126", "SB_127",
"SB_128", "SB_130", "SB_131", "SB_132", "SB_133", "SB_134", "SB_136",
"SB_137", "SB_138", "SB_139", "SB_140", "SB_141", "SB_143", "SB_146",
"SB_147", "SB_148", "SB_150", "SB_152", "SB_153", "SB_154", "SB_155",
"SB_156", "SB_157", "SB_158", "SB_159", "SB_160", "SB_161", "SB_162",
"SB_163", "SB_165", "SB_166", "SB_167", "SB_168", "SB_169", "SB_171",
"SB_172", "SB_174", "SB_175", "SB_176", "SB_180", "SB_181", "SB_182",
"SB_183", "SB_184", "SB_185", "SB_186", "SB_187", "SB_188", "SB_189",
"SB_190", "SB_191", "SB_192", "SB_193", "SB_194", "SB_195", "SB_196",
"SB_202", "SB_205", "SB_210", "SB_211", "SB_212", "SB_213", "SB_214",
"SB_215", "SB_216", "SB_217", "SB_218", "SB_219", "SB_220", "SB_221",
"SB_222", "SB_223", "SB_224", "SB_225", "SB_226", "SB_227", "SB_228",
"SB_230", "SB_231", "SB_232", "SB_233", "SB_234", "SB_235", "SB_236",
"SB_237", "SB_238", "SB_240", "SB_241", "SB_243", "SB_244", "SB_245",
"SB_246", "SB_247", "SB_248"), class = "factor"), DateTime = structure(c(1671854437,
1671868837, 1671883237, 1671897642, 1671912037, 1671926437, 1671940837,
1671955242, 1671969644, 1671984058, 1671998437, 1672012837, 1672027237,
1672041646, 1672056037, 1567447242, 1567454404, 1567461604, 1567468803,
1567476091, 1567483204, 1567490404, 1567497609, 1567612804, 1567620058
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), YNorthing = c(4640831.29,
4640687.169, 4642397.708, 4644840.306, 4646350.756, 4646919.927,
4646534.687, 4646865.79, 4647306.727, 4647076.159, 4649330.737,
4649855.958, 4649766.786, 4650129.319, 4650288.699, 4650026,
4649935, 4650148, 4650218, 4650226, 4650345, 4650342, 4650351,
4650040, 4649923), XEasting = c(13424219.597, 13425259.957, 13417594.318,
13415562.718, 13416285.702, 13415025.005, 13414998.247, 13415298.28,
13415021.033, 13416268.994, 13416506.255, 13416930.762, 13417068.436,
13417213.538, 13416885.97, 429788, 429323, 429119, 429078, 428974,
428886, 428883, 429023, 429870, 429600), x = c(424219.594584907,
425259.960358151, 417594.314800596, 415562.71890358, 416285.698693028,
415025.006157442, 414998.250352198, 415298.279154033, 415021.035323201,
416268.994737265, 416506.253844386, 416930.762803482, 417068.435627463,
417213.538974703, 416885.968245001, 429788.134621699, 429322.978335433,
429118.858664836, 429078.310284856, 428973.536615617, 428885.689295124,
428882.513327488, 429023.407508244, 429870.020439793, 429599.915982921
), y = c(4640831.28886158, 4640687.163379, 4642397.70379822,
4644840.30088953, 4646350.75440094, 4646919.92935201, 4646534.68665156,
4646865.79303352, 4647306.72834182, 4647076.15648437, 4649330.73207423,
4649855.95795628, 4649766.78705397, 4650129.32171694, 4650288.69561457,
4650026.21325154, 4649935.33876174, 4650147.91029761, 4650217.82758664,
4650226.20503632, 4650344.90043192, 4650342.04521013, 4650351.29340809,
4650039.8382759, 4649922.70138309), geometry = structure(list(
structure(c(-105.9138196, 41.9157991), class = c("XY", "POINT",
"sfg")), structure(c(-105.9012573, 41.9146003), class = c("XY",
"POINT", "sfg")), structure(c(-105.9939202, 41.9292418), class = c("XY",
"POINT", "sfg")), structure(c(-106.0187703, 41.9510235), class = c("XY",
"POINT", "sfg")), structure(c(-106.0102634, 41.9647027), class = c("XY",
"POINT", "sfg")), structure(c(-106.0255573, 41.9696934), class = c("XY",
"POINT", "sfg")), structure(c(-106.0258245, 41.9662213), class = c("XY",
"POINT", "sfg")), structure(c(-106.0222519, 41.9692353), class = c("XY",
"POINT", "sfg")), structure(c(-106.0256611, 41.9731762), class = c("XY",
"POINT", "sfg")), structure(c(-106.0105682, 41.9712334), class = c("XY",
"POINT", "sfg")), structure(c(-106.0080253, 41.9915617), class = c("XY",
"POINT", "sfg")), structure(c(-106.0029752, 41.9963364), class = c("XY",
"POINT", "sfg")), structure(c(-106.0013006, 41.9955479), class = c("XY",
"POINT", "sfg")), structure(c(-105.9996, 41.9988279), class = c("XY",
"POINT", "sfg")), structure(c(-106.0035772, 42.0002286), class = c("XY",
"POINT", "sfg")), structure(c(-105.847774, 41.999121), class = c("XY",
"POINT", "sfg")), structure(c(-105.853379, 41.998261), class = c("XY",
"POINT", "sfg")), structure(c(-105.855869, 42.000157), class = c("XY",
"POINT", "sfg")), structure(c(-105.856367, 42.000783), class = c("XY",
"POINT", "sfg")), structure(c(-105.857633, 42.000849), class = c("XY",
"POINT", "sfg")), structure(c(-105.858708, 42.00191), class = c("XY",
"POINT", "sfg")), structure(c(-105.858746, 42.001884), class = c("XY",
"POINT", "sfg")), structure(c(-105.857046, 42.00198), class = c("XY",
"POINT", "sfg")), structure(c(-105.846787, 41.999251), class = c("XY",
"POINT", "sfg")), structure(c(-105.850034, 41.998172), class = c("XY",
"POINT", "sfg"))), class = c("sfc_POINT", "sfc"), precision = 0, bbox = structure(c(xmin = -106.0258245,
ymin = 41.9146003, xmax = -105.846787, ymax = 42.00198), class = "bbox"), crs = structure(list(
input = "EPSG:4326", wkt = "GEOGCRS[\"WGS 84\",\n ENSEMBLE[\"World Geodetic System 1984 ensemble\",\n MEMBER[\"World Geodetic System 1984 (Transit)\"],\n MEMBER[\"World Geodetic System 1984 (G730)\"],\n MEMBER[\"World Geodetic System 1984 (G873)\"],\n MEMBER[\"World Geodetic System 1984 (G1150)\"],\n MEMBER[\"World Geodetic System 1984 (G1674)\"],\n MEMBER[\"World Geodetic System 1984 (G1762)\"],\n MEMBER[\"World Geodetic System 1984 (G2139)\"],\n ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n LENGTHUNIT[\"metre\",1]],\n ENSEMBLEACCURACY[2.0]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n CS[ellipsoidal,2],\n AXIS[\"geodetic latitude (Lat)\",north,\n ORDER[1],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n AXIS[\"geodetic longitude (Lon)\",east,\n ORDER[2],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n USAGE[\n SCOPE[\"Horizontal component of 3D system.\"],\n AREA[\"World.\"],\n BBOX[-90,-180,90,180]],\n ID[\"EPSG\",4326]]"), class = "crs"), n_empty = 0L)), sf_column = "geometry", agr = structure(c(AID = 1L,
DateTime = 1L, YNorthing = 1L, XEasting = 1L, x = 1L, y = 1L), levels = c("constant",
"aggregate", "identity"), class = "factor"), row.names = 145350:145374, class = c("sf",
"data.frame"))
- 50 rows of
Turbine_sf1
:
> dput(Turbine_sf1)
structure(list(name = c("Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Seven Mile Hill I & II",
"Seven Mile Hill I & II", "Seven Mile Hill I & II", "Ekola Flats",
"Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats",
"Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats",
"Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats", "Ekola Flats",
"Ekola Flats"), pronghorn_overlap = c("Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes",
"Yes", "Yes"), Phase1_Construction_Start_Date = structure(c(13977,
13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977,
13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977,
13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977, 13977,
13977, 13977, 13977, 13977, 13977, 13977, 18044, 18044, 18044,
18044, 18044, 18044, 18044, 18044, 18044, 18044, 18044, 18044,
18044, 18044, 18044, 18044, 18044), class = "Date"), Phase1_Construction_End_Date = structure(c(14183,
14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183,
14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183,
14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183, 14183,
14183, 14183, 14183, 14183, 14183, 14183, 18261, 18261, 18261,
18261, 18261, 18261, 18261, 18261, 18261, 18261, 18261, 18261,
18261, 18261, 18261, 18261, 18261), class = "Date"), Phase2_Construction_Start_Date = structure(c(NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, 18322, 18322, 18322, 18322, 18322, 18322, 18322, 18322, 18322,
18322, 18322, 18322, 18322, 18322, 18322, 18322, 18322), class = "Date"),
Phase2_Construction_End_Date = structure(c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
18551, 18551, 18551, 18551, 18551, 18551, 18551, 18551, 18551,
18551, 18551, 18551, 18551, 18551, 18551, 18551, 18551), class = "Date"),
Phase3_Construction_Start_Date = structure(c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_), class = "Date"), Phase3_Construction_End_Date = structure(c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_), class = "Date"), Operation_Date = structure(c(14232,
14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232,
14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232,
14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232, 14232,
14232, 14232, 14232, 14232, 14232, 14232, 18611, 18611, 18611,
18611, 18611, 18611, 18611, 18611, 18611, 18611, 18611, 18611,
18611, 18611, 18611, 18611, 18611), class = "Date"), Operation_End_Date = structure(c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_), class = "Date"), Second_Operation_Start_Date = structure(c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_), class = "Date"), Second_Operation_End_Date = structure(c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_), class = "Date"), geometry = structure(list(
structure(c(-106.38279, 41.957691), class = c("XY", "POINT",
"sfg")), structure(c(-106.434891, 41.971191), class = c("XY",
"POINT", "sfg")), structure(c(-106.411491, 41.946693), class = c("XY",
"POINT", "sfg")), structure(c(-106.37899, 41.919693), class = c("XY",
"POINT", "sfg")), structure(c(-106.365585, 41.945694), class = c("XY",
"POINT", "sfg")), structure(c(-106.43399, 41.969692), class = c("XY",
"POINT", "sfg")), structure(c(-106.426491, 41.957592), class = c("XY",
"POINT", "sfg")), structure(c(-106.412491, 41.959293), class = c("XY",
"POINT", "sfg")), structure(c(-106.411591, 41.948292), class = c("XY",
"POINT", "sfg")), structure(c(-106.372787, 41.940292), class = c("XY",
"POINT", "sfg")), structure(c(-106.366089, 41.926693), class = c("XY",
"POINT", "sfg")), structure(c(-106.41259, 41.943092), class = c("XY",
"POINT", "sfg")), structure(c(-106.377586, 41.917091), class = c("XY",
"POINT", "sfg")), structure(c(-106.412888, 41.956093), class = c("XY",
"POINT", "sfg")), structure(c(-106.383286, 41.950592), class = c("XY",
"POINT", "sfg")), structure(c(-106.366592, 41.921993), class = c("XY",
"POINT", "sfg")), structure(c(-106.36599, 41.928093), class = c("XY",
"POINT", "sfg")), structure(c(-106.411987, 41.957592), class = c("XY",
"POINT", "sfg")), structure(c(-106.425591, 41.962013), class = c("XY",
"POINT", "sfg")), structure(c(-106.411888, 41.952991), class = c("XY",
"POINT", "sfg")), structure(c(-106.366089, 41.923393), class = c("XY",
"POINT", "sfg")), structure(c(-106.365585, 41.952194), class = c("XY",
"POINT", "sfg")), structure(c(-106.425591, 41.959091), class = c("XY",
"POINT", "sfg")), structure(c(-106.435486, 41.962193), class = c("XY",
"POINT", "sfg")), structure(c(-106.372787, 41.936092), class = c("XY",
"POINT", "sfg")), structure(c(-106.420792, 41.971294), class = c("XY",
"POINT", "sfg")), structure(c(-106.372787, 41.938892), class = c("XY",
"POINT", "sfg")), structure(c(-106.383392, 41.947693), class = c("XY",
"POINT", "sfg")), structure(c(-106.383369, 41.949146), class = c("XY",
"POINT", "sfg")), structure(c(-106.366692, 41.916294), class = c("XY",
"POINT", "sfg")), structure(c(-106.382187, 41.927792), class = c("XY",
"POINT", "sfg")), structure(c(-106.43399, 41.968094), class = c("XY",
"POINT", "sfg")), structure(c(-106.411789, 41.945091), class = c("XY",
"POINT", "sfg")), structure(c(-106.366287, 41.956993), class = c("XY",
"POINT", "sfg")), structure(c(-106.202492, 41.625603), class = c("XY",
"POINT", "sfg")), structure(c(-106.19799, 41.642895), class = c("XY",
"POINT", "sfg")), structure(c(-106.291626, 41.913994), class = c("XY",
"POINT", "sfg")), structure(c(-106.196388, 41.645935), class = c("XY",
"POINT", "sfg")), structure(c(-106.209488, 41.611423), class = c("XY",
"POINT", "sfg")), structure(c(-106.202187, 41.628925), class = c("XY",
"POINT", "sfg")), structure(c(-106.201286, 41.636032), class = c("XY",
"POINT", "sfg")), structure(c(-106.278893, 41.941605), class = c("XY",
"POINT", "sfg")), structure(c(-106.355293, 41.963017), class = c("XY",
"POINT", "sfg")), structure(c(-106.328705, 41.919952), class = c("XY",
"POINT", "sfg")), structure(c(-106.341125, 41.919991), class = c("XY",
"POINT", "sfg")), structure(c(-106.205193, 41.618633), class = c("XY",
"POINT", "sfg")), structure(c(-106.328712, 41.923618), class = c("XY",
"POINT", "sfg")), structure(c(-106.250381, 41.917053), class = c("XY",
"POINT", "sfg")), structure(c(-106.253632, 41.919395), class = c("XY",
"POINT", "sfg")), structure(c(-106.341705, 41.923336), class = c("XY",
"POINT", "sfg")), structure(c(-106.207588, 41.615055), class = c("XY",
"POINT", "sfg"))), class = c("sfc_POINT", "sfc"), precision = 0, bbox = structure(c(xmin = -106.435486,
ymin = 41.611423, xmax = -106.196388, ymax = 41.971294), class = "bbox"), crs = structure(list(
input = "EPSG:4326", wkt = "GEOGCRS[\"WGS 84\",\n ENSEMBLE[\"World Geodetic System 1984 ensemble\",\n MEMBER[\"World Geodetic System 1984 (Transit)\"],\n MEMBER[\"World Geodetic System 1984 (G730)\"],\n MEMBER[\"World Geodetic System 1984 (G873)\"],\n MEMBER[\"World Geodetic System 1984 (G1150)\"],\n MEMBER[\"World Geodetic System 1984 (G1674)\"],\n MEMBER[\"World Geodetic System 1984 (G1762)\"],\n MEMBER[\"World Geodetic System 1984 (G2139)\"],\n ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n LENGTHUNIT[\"metre\",1]],\n ENSEMBLEACCURACY[2.0]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n CS[ellipsoidal,2],\n AXIS[\"geodetic latitude (Lat)\",north,\n ORDER[1],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n AXIS[\"geodetic longitude (Lon)\",east,\n ORDER[2],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n USAGE[\n SCOPE[\"Horizontal component of 3D system.\"],\n AREA[\"World.\"],\n BBOX[-90,-180,90,180]],\n ID[\"EPSG\",4326]]"), class = "crs"), n_empty = 0L)), sf_column = "geometry", agr = structure(c(name = 1L,
pronghorn_overlap = 1L, Phase1_Construction_Start_Date = 1L,
Phase1_Construction_End_Date = 1L, Phase2_Construction_Start_Date = 1L,
Phase2_Construction_End_Date = 1L, Phase3_Construction_Start_Date = 1L,
Phase3_Construction_End_Date = 1L, Operation_Date = 1L, Operation_End_Date = 1L,
Second_Operation_Start_Date = 1L, Second_Operation_End_Date = 1L
), levels = c("constant", "aggregate", "identity"), class = "factor"), row.names = 225:275, class = c("sf",
"data.frame"))
I'd like to end up with a new column in the pronghorn_sf object (which I will probably convert to a dataframe or datatable) that includes distance in meters to the nearest turbine under construction. If an animal's timestamp falls outside of turbine construction periods, I'd like to populate those rows with NAs.
Share Improve this question edited Nov 24, 2024 at 16:09 Friede 8,4512 gold badges9 silver badges29 bronze badges asked Nov 19, 2024 at 21:53 c.rob4c.rob4 133 bronze badges 5 |2 Answers
Reset to default 1I believe we can simply this a bit by first moving from POINT
s to MULTIPOINT
s for turbine locations so we'd have a set of points for each unique construction date range.
From there we can use date ranges and animal observation dates with overlap join to get an sf
object with 2 geometry columns, one with POINT
s and another with MULTIPOINT
s; using those in st_distance()
will get us distances from every animal location to the closest turbine that was under construction at that date. Or NA
if there were no such turbines.
Following assumes that all dates and DateTime values are in UTC, for data from GPS trackers this is probably true, but construction dates are likely in local timezone. Perhaps something to consider if 6 ... 7-hour difference happens to play a role here.
Turbines aggregated to MULTIPOINT
s by construction date ranges:
library(dplyr, warn.conflicts = FALSE)
library(tidyr)
library(sf)
# tranform to a tidy frame with one set of start/end dates and a phase column;
# group by dates (and phase, if needed) and summarise POINTs to MULTIPOINTs
turbine_constr_sf <-
Turbine_sf |>
select(name, contains("Construction")) |>
mutate(id = row_number(), .before = 1) |>
pivot_longer(
contains("Construction"),
names_pattern = "Phase(\\d+)_(.*)",
names_to = c("phase", "label"),
values_drop_na = TRUE
) |>
pivot_wider(names_from = label) |>
# include `phase` in grouping variables if it must be tracked
summarise(across(geometry, st_union), .by = c(Construction_Start_Date, Construction_End_Date))
turbine_constr_sf
#> Simple feature collection with 3 features and 2 fields
#> Geometry type: MULTIPOINT
#> Dimension: XY
#> Bounding box: xmin: -106.4355 ymin: 41.61142 xmax: -106.1964 ymax: 41.97129
#> Geodetic CRS: WGS 84
#> # A tibble: 3 × 3
#> Construction_Start_Date Construction_End_Date geometry
#> <date> <date> <MULTIPOINT [°]>
#> 1 2008-04-08 2008-10-31 ((-106.4208 41.97129), (-106.434 41.96809), (-106.434 41.96969), (-106.4349 41.97119),...
#> 2 2019-05-28 2019-12-31 ((-106.3553 41.96302), (-106.2504 41.91705), (-106.3411 41.91999), (-106.3287 41.91995...
#> 3 2020-03-01 2020-10-16 ((-106.3553 41.96302), (-106.2504 41.91705), (-106.3411 41.91999), (-106.3287 41.91995...
Join turbine MULTIPOINT
s by date, get distance to the closest under construction turbine :
# join turbine_constr_sf by date range, we'll end up with 2 geometry columns;
# get distances between 2 geometry sets, by elements
pronghorn_sf |>
mutate(date = as.Date(DateTime)) |>
# sf::left_join.sf() will not accept 2 `sf` objects,
# drop sf class but keep (renamed) geom.column
left_join(
as.data.frame(turbine_constr_sf) |> select(ends_with("Date"), geom_turbines = geometry),
by = join_by(between(date, Construction_Start_Date, Construction_End_Date))
) |>
mutate(construction_distance = st_distance(geometry, geom_turbines, by_element = TRUE)) |>
select(-c(date, geom_turbines, matches("Construction.*Date"))) |>
print(n = 30)
#> Simple feature collection with 25 features and 7 fields
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: -106.0258 ymin: 41.9146 xmax: -105.8468 ymax: 42.00198
#> Geodetic CRS: WGS 84
#> AID DateTime YNorthing XEasting x y construction_distance geometry
#> 1 SB_101 2022-12-24 04:00:37 4640831 13424220 424219.6 4640831 NA [m] POINT (-105.9138 41.9158)
#> 2 SB_101 2022-12-24 08:00:37 4640687 13425260 425260.0 4640687 NA [m] POINT (-105.9013 41.9146)
#> 3 SB_101 2022-12-24 12:00:37 4642398 13417594 417594.3 4642398 NA [m] POINT (-105.9939 41.92924)
#> 4 SB_101 2022-12-24 16:00:42 4644840 13415563 415562.7 4644840 NA [m] POINT (-106.0188 41.95102)
#> 5 SB_101 2022-12-24 20:00:37 4646351 13416286 416285.7 4646351 NA [m] POINT (-106.0103 41.9647)
#> 6 SB_101 2022-12-25 00:00:37 4646920 13415025 415025.0 4646920 NA [m] POINT (-106.0256 41.96969)
#> 7 SB_101 2022-12-25 04:00:37 4646535 13414998 414998.3 4646535 NA [m] POINT (-106.0258 41.96622)
#> 8 SB_101 2022-12-25 08:00:42 4646866 13415298 415298.3 4646866 NA [m] POINT (-106.0223 41.96924)
#> 9 SB_101 2022-12-25 12:00:44 4647307 13415021 415021.0 4647307 NA [m] POINT (-106.0257 41.97318)
#> 10 SB_101 2022-12-25 16:00:58 4647076 13416269 416269.0 4647076 NA [m] POINT (-106.0106 41.97123)
#> 11 SB_101 2022-12-25 20:00:37 4649331 13416506 416506.3 4649331 NA [m] POINT (-106.008 41.99156)
#> 12 SB_101 2022-12-26 00:00:37 4649856 13416931 416930.8 4649856 NA [m] POINT (-106.003 41.99634)
#> 13 SB_101 2022-12-26 04:00:37 4649767 13417068 417068.4 4649767 NA [m] POINT (-106.0013 41.99555)
#> 14 SB_101 2022-12-26 08:00:46 4650129 13417214 417213.5 4650129 NA [m] POINT (-105.9996 41.99883)
#> 15 SB_101 2022-12-26 12:00:37 4650289 13416886 416886.0 4650289 NA [m] POINT (-106.0036 42.00023)
#> 16 SB_103 2019-09-02 18:00:42 4650026 429788 429788.1 4650026 34518.99 [m] POINT (-105.8478 41.99912)
#> 17 SB_103 2019-09-02 20:00:04 4649935 429323 429323.0 4649935 34046.96 [m] POINT (-105.8534 41.99826)
#> 18 SB_103 2019-09-02 22:00:04 4650148 429119 429118.9 4650148 33904.87 [m] POINT (-105.8559 42.00016)
#> 19 SB_103 2019-09-03 00:00:03 4650218 429078 429078.3 4650218 33884.16 [m] POINT (-105.8564 42.00078)
#> 20 SB_103 2019-09-03 02:01:31 4650226 428974 428973.5 4650226 33785.52 [m] POINT (-105.8576 42.00085)
#> 21 SB_103 2019-09-03 04:00:04 4650345 428886 428885.7 4650345 33732.64 [m] POINT (-105.8587 42.00191)
#> 22 SB_103 2019-09-03 06:00:04 4650342 428883 428882.5 4650342 33728.82 [m] POINT (-105.8587 42.00188)
#> 23 SB_103 2019-09-03 08:00:09 4650351 429023 429023.4 4650351 33866.76 [m] POINT (-105.857 42.00198)
#> 24 SB_103 2019-09-04 16:00:04 4650040 429870 429870.0 4650040 34601.49 [m] POINT (-105.8468 41.99925)
#> 25 SB_103 2019-09-04 18:00:58 4649923 429600 429599.9 4649923 34311.15 [m] POINT (-105.85 41.99817)
If you have partially overlapping construction date ranges in your actual dataset, your row count should increase and you should probably apply another filter to choose between matched multipoints. And if there are so many date range overlaps that resulting row count explodes, this whole approach should probably be reviewed.
We suspect an R-like way to do the fitering is to merge the objects.
You provide objects of class data.frame
and sf
. We try to avoid merge.sf()
, so we explicitly use as.data.frame()
which might be the easiest. One reason for this is that merge.sf()
accepts only one sf
-object. We could further reduce the code if we knew the desired output better.
Assumptions
- all dates and datetimes are in UTC
pronghorn_sf
andTurbine_sf
have the samecrs
- pronghorns can be uniquely identified by
AID
Advice
- Select columns of relevance
- Use shorter variable names
library(sf)
as.data.frame(pronghorn_sf) |>
transform(date=as.Date(DateTime, tz="UTC")) |>
merge(transform(as.data.frame(Turbine_sf), t_id=seq(nrow(Turbine_sf))), by=NULL) |>
subset(date>=Phase1_Construction_Start_Date & date<=Phase1_Construction_End_Date) |>
st_as_sf() |>
transform(ed=st_distance(geometry.x, geometry.y, by_element=TRUE),
AID=droplevels(AID)) |>
tapply(~AID+DateTime, subset, ed==min(ed)) |> do.call(what="rbind") |>
as.data.frame() |>
subset(select=c(AID, DateTime, ed, t_id, name)) |>
merge(as.data.frame(pronghorn_sf), y=_, by=c("AID", "DateTime"), all.x=TRUE)
AID DateTime YNorthing XEasting x y geometry ed t_id name
1 SB_101 2022-12-24 04:00:37 4640831 13424220 424219.6 4640831 POINT (-105.9138 41.9158) NA [m] NA <NA>
2 SB_101 2022-12-24 08:00:37 4640687 13425260 425260.0 4640687 POINT (-105.9013 41.9146) NA [m] NA <NA>
3 SB_101 2022-12-24 12:00:37 4642398 13417594 417594.3 4642398 POINT (-105.9939 41.92924) NA [m] NA <NA>
4 SB_101 2022-12-24 16:00:42 4644840 13415563 415562.7 4644840 POINT (-106.0188 41.95102) NA [m] NA <NA>
5 SB_101 2022-12-24 20:00:37 4646351 13416286 416285.7 4646351 POINT (-106.0103 41.9647) NA [m] NA <NA>
6 SB_101 2022-12-25 00:00:37 4646920 13415025 415025.0 4646920 POINT (-106.0256 41.96969) NA [m] NA <NA>
7 SB_101 2022-12-25 04:00:37 4646535 13414998 414998.3 4646535 POINT (-106.0258 41.96622) NA [m] NA <NA>
8 SB_101 2022-12-25 08:00:42 4646866 13415298 415298.3 4646866 POINT (-106.0223 41.96924) NA [m] NA <NA>
9 SB_101 2022-12-25 12:00:44 4647307 13415021 415021.0 4647307 POINT (-106.0257 41.97318) NA [m] NA <NA>
10 SB_101 2022-12-25 16:00:58 4647076 13416269 416269.0 4647076 POINT (-106.0106 41.97123) NA [m] NA <NA>
11 SB_101 2022-12-25 20:00:37 4649331 13416506 416506.3 4649331 POINT (-106.008 41.99156) NA [m] NA <NA>
12 SB_101 2022-12-26 00:00:37 4649856 13416931 416930.8 4649856 POINT (-106.003 41.99634) NA [m] NA <NA>
13 SB_101 2022-12-26 04:00:37 4649767 13417068 417068.4 4649767 POINT (-106.0013 41.99555) NA [m] NA <NA>
14 SB_101 2022-12-26 08:00:46 4650129 13417214 417213.5 4650129 POINT (-105.9996 41.99883) NA [m] NA <NA>
15 SB_101 2022-12-26 12:00:37 4650289 13416886 416886.0 4650289 POINT (-106.0036 42.00023) NA [m] NA <NA>
16 SB_103 2019-09-02 18:00:42 4650026 429788 429788.1 4650026 POINT (-105.8478 41.99912) 34518.99 [m] 48 Ekola Flats
17 SB_103 2019-09-02 20:00:04 4649935 429323 429323.0 4649935 POINT (-105.8534 41.99826) 34046.96 [m] 48 Ekola Flats
18 SB_103 2019-09-02 22:00:04 4650148 429119 429118.9 4650148 POINT (-105.8559 42.00016) 33904.87 [m] 48 Ekola Flats
19 SB_103 2019-09-03 00:00:03 4650218 429078 429078.3 4650218 POINT (-105.8564 42.00078) 33884.16 [m] 48 Ekola Flats
20 SB_103 2019-09-03 02:01:31 4650226 428974 428973.5 4650226 POINT (-105.8576 42.00085) 33785.52 [m] 48 Ekola Flats
21 SB_103 2019-09-03 04:00:04 4650345 428886 428885.7 4650345 POINT (-105.8587 42.00191) 33732.64 [m] 48 Ekola Flats
22 SB_103 2019-09-03 06:00:04 4650342 428883 428882.5 4650342 POINT (-105.8587 42.00188) 33728.82 [m] 48 Ekola Flats
23 SB_103 2019-09-03 08:00:09 4650351 429023 429023.4 4650351 POINT (-105.857 42.00198) 33866.76 [m] 48 Ekola Flats
24 SB_103 2019-09-04 16:00:04 4650040 429870 429870.0 4650040 POINT (-105.8468 41.99925) 34601.49 [m] 48 Ekola Flats
25 SB_103 2019-09-04 18:00:58 4649923 429600 429599.9 4649923 POINT (-105.85 41.99817) 34311.15 [m] 48 Ekola Flats
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742396227a4435999.html
dput(Pronghorn_sf)
etc into your question. Do not use pictures. Have a read stackoverflow/questions/5963269/… – Friede Commented Nov 19, 2024 at 21:58