Манипулировать матрицей на основе двух пороговых векторов в R

#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)