You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建包含全部节点但仅对应年份边子集的network对象?

问题描述

我用下面的代码创建网络:

library(network)

###create a network
edges_list <- lapply(eyears, function(x){network(edges[edges$Year_n <= x ,1:2],directed = FALSE, vertex.attr = nodes)})

其中:

  • eyears是Year_n的向量
  • edges是首列为from和to列的数据框
  • nodes是首列为nodeID(与from和to列匹配)的数据框

我需要调整代码,让edges_list的每个元素都包含全部节点以及对应年份的边。

数据结构信息

str(eyears)
 num [1:9] 1974 1976 1978 1980 1982 ...
dput(eyears)
c(1974, 1976, 1978, 1980, 1982, 1984, 1986, 1988, 1990)
str(edges)
'data.frame':   524 obs. of  8 variables:
 $ from  : int  212 208 210 214 215 295 212 209 136 64 ...
 $ to    : int  208 210 214 215 291 290 209 136 133 60 ...
 $ cat   : num  1 2 3 4 5 6 7 8 9 10 ...
 $ Year  : num  1975 1978 1980 1980 1981 ...
 $ global: num  NA NA NA NA NA NA NA NA NA NA ...
 $ length: num  98624 15078 232283 199234 78635 ...
 $ PLAN  : num  0 0 0 0 0 0 0 1 1 1 ...
 $ Year_n: num  1975 1978 1980 1980 1981 ...
dput(edges[1:10, 1:8])
structure(list(from = c(212L, 208L, 210L, 214L, 215L, 295L, 212L, 
209L, 136L, 64L), to = c(208L, 210L, 214L, 215L, 291L, 290L, 
209L, 136L, 133L, 60L), cat = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10
), Year = c(1975, 1978, 1980, 1980, 1981, 1981, 1975, 1972, 1972, 
1977), global = c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), length = c(98623.6375924798, 
15077.7144003721, 232283.331561727, 199233.502207442, 78635.0389206188, 
131367.696300722, 37153.912532765, 56431.0393784146, 42069.0250811096, 
94832.0618165286), PLAN = c(0, 0, 0, 0, 0, 0, 0, 1, 1, 1), Year_n = c(1975, 
1978, 1980, 1980, 1981, 1981, 1974, 1972, 1972, 1976)), row.names = c(NA, 
10L), class = "data.frame")

dput(nodes[1:5, 1:8])
structure(list(nodeID = c(212L, 208L, 210L, 214L, 215L), geometry = structure(list(
    structure(c(2.41222419606553, 6.37236234905488), class = c("XY", 
    "POINT", "sfg")), structure(c(2.06074739865659, 7.18774854505763
    ), class = c("XY", "POINT", "sfg")), structure(c(2.08122414661067, 
    7.32181538325724), class = c("XY", "POINT", "sfg")), structure(c(2.62560447031769, 
    9.34015700977641), class = c("XY", "POINT", "sfg")), structure(c(2.85342785762295, 
    11.1178227489884), class = c("XY", "POINT", "sfg"))), class = c("sfc_POINT", 
"sfc"), precision = 0, bbox = structure(c(xmin = 2.06074739865659, 
ymin = 6.37236234905488, xmax = 2.85342785762295, ymax = 11.1178227489884
), class = "bbox"), crs = structure(list(input = "GCS_WGS_84_CRS84", 
    wkt = "GEOGCRS[\"GCS_WGS_84_CRS84\",\n    DATUM[\"World Geodetic System 1984\",\n        ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n            LENGTHUNIT[\"metre\",1]],\n        ID[\"EPSG\",6326]],\n    PRIMEM[\"Greenwich\",0,\n        ANGLEUNIT[\"Degree\",0.0174532925199433]],\n    CS[ellipsoidal,2],\n        AXIS[\"longitude\",east,\n            ORDER[1],\n            ANGLEUNIT[\"Degree\",0.0174532925199433]],\n        AXIS[\"latitude\",north,\n            ORDER[2],\n            ANGLEUNIT[\"Degree\",0.0174532925199433]]]"), class = "crs"), n_empty = 0L), 
    mother1946 = c("FRA", "FRA", "FRA", "FRA", "FRA"), country_name = c("Benin", 
    "Benin", "Benin", "Benin", "Benin"), iso3c = c("BEN", "BEN", 
    "BEN", "BEN", "BEN"), dist2river = c(206.4402, 200.9958, 
    201.0137, 212.8585, 98.41196), dist2coast = c(0, 88.95607, 
    111.1951, 331.5523, 525.4953), dist2emst = c(12.10693, 3.912999, 
    19.6633, 39.41241, 233.1657)), row.names = c(NA, -5L), sf_column = "geometry", agr = structure(c(nodeID = NA_integer_, 
mother1946 = NA_integer_, country_name = NA_integer_, iso3c = NA_integer_, 
dist2river = NA_integer_, dist2coast = NA_integer_, dist2emst = NA_integer_
), levels = c("constant", "aggregate", "identity"), class = "factor"), class = c("sf", 
"tbl_df", "tbl", "data.frame"))
解决方案

原代码的问题是network()函数默认只保留边数据中出现的节点,不会自动包含所有节点。要强制包含全部节点,需要指定vertices参数传入所有节点ID,同时保留节点属性。

修改后的代码如下:

library(network)

# 提取所有节点ID
all_nodes <- nodes$nodeID

# 创建包含全部节点的网络列表
edges_list <- lapply(eyears, function(x){
  # 筛选当前年份及之前的边
  filtered_edges <- edges[edges$Year_n <= x, c("from", "to")]
  # 创建网络:指定vertices包含所有节点,同时传入节点属性
  network(filtered_edges, 
          directed = FALSE, 
          vertices = all_nodes,
          vertex.attr = nodes,
          vertex.attrnames = colnames(nodes))
})

关键说明

  • vertices = all_nodes:强制网络包含所有节点,即使部分节点在当前年份没有关联边
  • vertex.attr = nodes:保留节点的所有属性数据
  • vertex.attrnames = colnames(nodes):显式指定属性列名,避免列名匹配异常导致属性丢失

你可以用以下代码验证每个网络是否包含全部节点:

# 检查第一个网络的节点数是否等于总节点数
length(edges_list[[1]]$val$vertex.names) == nrow(nodes)

内容的提问来源于stack exchange,提问作者Sulz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 17:59:51