Найти наименьшее число из строки в матрице, отфильтрованной по значению во фрейме данных? - PullRequest
1 голос
/ 03 февраля 2020

У меня есть набор данных местоположений, и я пытаюсь найти расстояние до ближайшей зоны метро. Пример:

library(SpatialEpi)

df <- as.data.frame(cbind(c(100124, 100460, 100484, 100676, 100820, 2608640), c(2563, 4325, 637,330, 15278, 209880), c(31.56795, 33.60575, 34.20269, 32.87949, 33.24476, 33.52775), c(-85.25130, -86.94917, -87.17785, -87.73878, -86.76102, -86.79905), c(0,0,0,0,0,1)))
colnames(df) <- c("GEOID", "population", "latitude", "longitude", "is_metro")

Я создал матрицу расстояний, используя dist

df_dist <- as.matrix(dist(latlong2grid(matrix(c(df$longitude, df$latitude), ncol = 2, nrow=nrow(df)))))

Теперь я хотел бы, чтобы каждая строка возвращала расстояние до ближайшего значения где is_metro = 1. Так, например, ниже, в строке 1 самым близким значением является 5-й столбец, но я хочу вернуть 6-й столбец, потому что это столбец, в котором эквивалентная строка равна is_metro==1. Для этого конкретного примера мне понадобятся все эти строки, чтобы показать соответствующее расстояние до строки 6, но в полном наборе данных у меня есть почти 20 тыс. Записей и много записей, где is_metro==1, и мне нужна ближайшая.

enter image description here

Я надеюсь, что все имеет смысл. Где я могу начать?

1 Ответ

1 голос
/ 03 февраля 2020

Мы можем использовать max.col для отрицательно преобразованного df_dist после установки значений в столбцах, которые равны 0 для 'is_metro' в 'Inf'. max.col получит индекс максимального значения (изменяя его на отрицательный -, он дает индекс минимального значения), а затем извлечет значения с индексом строки / столбца

tmp <- (NA^!df$is_metro[col(df_dist)]) * df_dist
df_dist[cbind(seq_len(nrow(df_dist)), 
         max.col(-replace(tmp, is.na(tmp), Inf), 'first'))]

Или другой вариант: pmin

df$closest_metro  <- do.call(pmin, c(asplit(tmp, 2), na.rm = TRUE))
df$closest_metro 
#[1] 256.04080   0.00000  69.25702 105.97461  31.62297   0.00000

data

df <- structure(list(GEOID = c(100124, 100460, 100484, 100676, 100820, 
2608640), population = c(2563, 4325, 637, 330, 15278, 209880), 
    latitude = c(31.56795, 33.60575, 34.20269, 32.87949, 33.24476, 
    33.52775), longitude = c(-85.2513, -86.94917, -87.17785, 
    -87.73878, -86.76102, -86.79905), is_metro = c(0, 1, 0, 0, 
    0, 1)), row.names = c(NA, -6L), class = "data.frame")
...