簡體   English   中英

R - 根據閾值為所有組合創建向量列表

[英]R - Create list of vectors for all combinations combined based on threshold value

問題:我有一個 dataframe(參見示例數據),其中包含空間點(“siteA”和“siteB”)之間的距離以及它們是否彼此太近(“close”)。 我需要一種將彼此靠近的站點組合成一個向量的方法。 在示例數據中:站點 1 靠近站點 3,但遠離站點 2。但是,站點 3 靠近站點 2。因此,我需要一種方法將它們組合成列表中的一個向量(對於每個組),並且有一個 output,其中站點 1、2、3 在一個向量中; 位點 4 和 5 在一個向量中。 然后將所有向量組合在一個列表中。

# ----------------------------- #
# --- Example table of data --- #
# ----------------------------- #
   siteA siteB     distance close
1      1     2   2913.35364 FALSE
2      1     3   1894.23651  TRUE
3      1     4  96487.01697 FALSE
4      1     5  96485.33550 FALSE
5      2     3   1642.27932  TRUE
6      2     4  93185.78766 FALSE
7      2     5  93183.73986 FALSE
8      3     4 102445.53187 FALSE
9      3     5 102448.58978 FALSE
10     4     5      3.47365  TRUE
# ----------------------------- #


# Example console output for expected results:
> expected_results
[[1]]
[1] 1 2 3

[[2]]
[1] 4 5

該表已經包含站點對之間的所有組合,但我需要所有重疊對的組合(如果 close = TRUE)作為每個組的一個向量(例如上面的預期結果)。

在示例數據中只有 5 個站點,但這些站點可以從 2 到 20+ 不等,並且在示例中,距離取為 2500,低於該距離的任何位置都被認為是接近的,但是,此值也可能因用戶輸入而異.

# Example dataset
df <- data.frame(
  siteA = c(1, 1, 1, 1, 2, 2, 2, 3, 3, 4),
  siteB = c(2, 3, 4, 5, 3, 4, 5, 4, 5, 5),
  distance = c(2913.35364, 1894.23651, 96487.01697, 96485.33550, 1642.27932,  93185.78766, 93183.73986, 102445.53187, 102448.58978, 3.47365),
  close = c(FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE)
)

我正在努力尋找解決方案,任何指導將不勝感激。 對於沒有提供示例代碼,我深表歉意,我嘗試了多種循環方法,但都以慘淡的方式結束。

謝謝!

它可能可以通過很少的改進以更好的方式完成。

代碼

library(tidyverse)

df <- data.frame(
  siteA = c(1,1,1,1,2,2,2,3,3,4),
  siteB = c(2,3,4,5,3,4,5,4,5,5),
  close = c(F,T,F,F,T,F,F,F,F,T)
)

unvisited_sites <- df %>%
  select(contains("site")) %>%
  unlist() %>%
  unique()

site_groups <- list()
i <- 1
while(length(unvisited_sites) > 0){
  
  visited_sites <- NULL
  S <- unvisited_sites[[1]]
  while(length(S) > 0){
    
    u <- S[[1]]
    
    sites <- df %>%
      filter(siteA == u | siteB == u) %>%
      filter(close == TRUE) %>%
      select(siteA, siteB) %>%
      unlist() %>%
      unique() %>%
      intersect(unvisited_sites)
    
    visited_sites <- union(visited_sites, sites)
    unvisited_sites <- setdiff(unvisited_sites, u)
    S <- union(S, intersect(sites, unvisited_sites)) %>% setdiff(u)
  }
  
  site_groups[[i]] <- visited_sites %>% sort()
  i <- i + 1
}

OUTPUT

site_groups
[[1]]
[1] 1 2 3

[[2]]
[1] 4 5

我不完全確定這會擴展到更復雜的網絡,但它適用於上述數據。

aggregate(siteA ~ siteB, df[df$close == T,], paste)

  siteB siteA
1     3  1, 2
2     5     4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM