R: Как подать заявку на l oop только для строк с подмножеством в кадре данных - PullRequest
1 голос
/ 09 июля 2020

У меня есть фрейм данных

head(df)
                 time     LON     LAT MAG
1 1965-01-12 13:32:25 87.8286 27.3829 6.1
2 1965-01-12 13:55:20 87.6567 27.3269 5.3
3 1965-02-18 04:26:36 94.1127 25.0251 5.5
4 1965-02-25 10:34:07 94.5712 23.6672 5.3
5 1965-04-11 22:33:05 92.2023 26.6941 5.1
6 1965-04-30 07:13:25 95.8880 28.3319 4.4

Это время, место и сила землетрясений, он содержит около 4000 строк.

Я выделил события MAG >= 5 и для каждого такого события Хочу проверить в ближайшие 10 дней после мероприятия. А затем выведите события, которые находятся в радиусе 50 км в этом 10-дневном временном окне для каждого события MAG >= 5.

library(dplyr)
library(lubridate)
library(geosphere)

t <- filter(df, MAG >= 5) 

for (i in 1:nrow(t)){
  data1 <- filter(t, time <= time[i] + days(10) & time >= time[i])
  p <- select(data1, LON, LAT)
  l <- distm(p)[1,]            # first row of the distance matrix between each event
  for (j in 1:length(l)){
    if (l[j] <= 50000 & l[j] != 0){       # within 50 kms and excluding the event itself
      print(data1[j,])
    }
  }
}

Но это проверяет только значения в кадре данных t. Как проверить в течение следующих 10 дней событие MAG >= 5 в исходном фрейме данных df

1 Ответ

0 голосов
/ 09 июля 2020

Рассмотрите подход на основе наборов с использованием merge и избегайте вложенных циклов for. В частности, запустите подмножество перекрестных соединений, сопоставив землетрясения силой более 5 баллов с каждым другим землетрясением в течение 10 дней и 50 км. При N = 4000 строк ниже должно быть возможным. Ниже используется базовый код R, но его можно настроить для методов dplyr (filter, inner_join, arrange).

mag5_df <- subset(df, MAG >= 5) 

# CROSS JOIN PAIRING OF MAG 5 EVENTS AND ALL OTHER EARTHQUAKES WITHIN 10 DAYS
merge_df <- subset(merge(mag5, df, by=NULL, suffixes=c("", "_")), 
                   time_ >= time & time_ <= time + lubridate::days(10))

# CALCULATE DISTANCE BETWEEN LAT/LON PAIRS
merge_df$dist_m <- geosphere::distVincentyEllipsoid(merge_df[c("LON", "LAT")], 
                                                    merge_df[c("LON_", "LAT_")])

# SUBSET TO WITHIN 50 KM AND ORDER OUTPUT BY MAG 5 LAT/LON, TIME, AND DISTANCE
near50km_df <- subset(merge_df, dist_m > 0 & dist_m <= 5E4)
near50km_df <- data.frame(with(near50km_df, near50km_df[order(LAT, LON, time, dist_m),],
                          row.names = NULL)

# DISPLAY ALL MAG 5 EVENTS AND QUALIFIED PAIRS
near50km_df
...