#r #matrix
#r #матрица
Вопрос:
Я не знаю точно, как мне следует сформулировать эту проблему, и не могу придумать ни одного примера того, как ее решить. Я придумал решение, но мне интересно, есть ли более простой или эффективный способ справиться с этим.
Я работаю с матрицей расстояний между отдельными лицами и событиями, и я хочу преобразовать матрицу на основе характеристик событий и отдельных лиц. В этом случае я хочу знать, подвергался ли человек воздействию события на определенном расстоянии на основе других критериев.
Допустим, у нас есть два вектора, один из 4 индивидуумов, а другой из 3 событий. Мы получаем матрицу расстояний в км между отдельными лицами и событиями:
> dist_mat = matrix(runif(12, 1, 100), ncol = 3)
> dist_mat
[,1] [,2] [,3]
[1,] 21.318423 89.79522 75.29824
[2,] 36.812542 18.28413 92.90719
[3,] 45.012960 89.11778 38.55608
[4,] 8.470336 46.17020 26.67135
Кроме того, я знаю, когда люди родились и когда произошли события, которые хранятся в двух векторах:
> event_year = c(2003, 2005, 2009)
> indiv_born = c(2004, 2004, 2008, 2008)
Моя цель — узнать, подвергался ли человек воздействию события, произошедшего после ее рождения и в пределах, скажем, 30 км. Мое решение на данный момент состоит в том, чтобы разложить векторы года на матрицы и обработать их оттуда, а затем использовать rowSums
для получения индикатора того, подвергался ли человек такому событию:
> event_year_m = matrix(rep(event_year, each = nrow(x1)), ncol = ncol(x1))
> indiv_born_m = matrix(rep(indiv_year, each = ncol(x1)), byrow = TRUE, ncol = ncol(x1))
> event_year_m
[,1] [,2] [,3]
[1,] 2003 2005 2009
[2,] 2003 2005 2009
[3,] 2003 2005 2009
[4,] 2003 2005 2009
> indiv_year_m
[,1] [,2] [,3]
[1,] 2004 2004 2004
[2,] 2004 2004 2004
[3,] 2008 2008 2008
[4,] 2008 2008 2008
> dist_mat[event_year_m < indiv_year_m] = NA
> dist_mat[dist_mat < 30] = 1
> dist_mat[dist_mat >= 30] = 0
> dist_mat
[,1] [,2] [,3]
[1,] NA 0 0
[2,] NA 1 0
[3,] NA NA 0
[4,] NA NA 1
> indiv_exposure = rowSums(dist_mat, na.rm = TRUE)
[1] 0 1 0 1
Имеет ли это смысл? Нет ли более простого способа сделать это? Иметь только один вектор было бы проще, но я не могу понять это в случае пороговых значений, зависящих от строки и столбца.
Ответ №1:
Мы можем сделать это в одной строке (или разделить на 2 строки для наглядности), используя col/row
для репликации ‘event_year’ и ‘indiv_born’, изменить логический вектор на NA
, когда ‘event_year’ меньше, чем ‘indiv_born’, умножить на dist_mat
так, чтобы NA
осталось NA, преобразовать в логическую матрицу с помощью < 30
и получить rowSums
rowSums((dist_mat * NA^(event_year[col(dist_mat)] <
indiv_born[row(dist_mat)])) < 30, na.rm = TRUE)