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

如何修复交互矩阵生成时的subscript out of bounds错误?

问题:创建交互矩阵时出现下标越界错误

运行代码创建猪只交互矩阵时,出现以下错误:

Error in interaction_matrix[as.numeric(pig_id), as.numeric(closest_pig)] : 
  subscript out of bounds

使用的代码如下:

create_interaction_matrices <- function(nm, behavior_code = "AFF", select_every = 10, nsel = 25) {
  NNdatafull <- read_excel(nm, sheet = 1)
  colnames(NNdatafull) <- c("Date", "Time", "Pen", "Pig_ID", "Distance", "Closest_Pig", "Behavior", "Orientation", "Location")
  datelevels <- unique(NNdatafull$Date)
  
  interaction_matrices <- list()
  
  for (date in datelevels) {
    mdat <- filter(NNdatafull, Date == date)
    mdat <- filter(mdat, Behavior == behavior_code)
    
    # Get unique pig IDs from both Pig_ID and Closest_Pig columns
    unique_pigs <- union(unique(mdat$Pig_ID), unique(mdat$Closest_Pig))
    
    # Initialize interaction matrix with the size based on the number of unique pigs
    interaction_matrix <- matrix(0, nrow = length(unique_pigs), ncol = length(unique_pigs))
    
    for (i in 1:nsel) {
      time <- min(mdat$Time) + (i - 1) * (60 * select_every)
      time_data <- filter(mdat, Time == time)
      interacting_pigs <- unique(time_data$Pig_ID)
      closest_pigs <- unique(time_data$Closest_Pig)
      
      # Update interaction matrix based on pig ID to closest pig interactions
      for (pig_id in interacting_pigs) {
        closest_pig <- time_data$Closest_Pig[time_data$Pig_ID == pig_id]
        # Increment the value in the interaction matrix
        interaction_matrix[as.numeric(pig_id), as.numeric(closest_pig)] <- interaction_matrix[as.numeric(pig_id), as.numeric(closest_pig)] + 1
      }
    }
    interaction_matrices[[as.character(date)]] <- interaction_matrix
  }
  return(interaction_matrices)
}

你推测的原因正确:矩阵维度由unique_pigs的数量决定,但部分Pig_ID的数值大于猪只总数(比如栏内仅13头猪,却存在ID为16的个体),直接用ID数值作为矩阵下标会超出范围。


解决方案:将猪ID映射为连续索引

核心思路是把非连续的猪ID转换成从1开始的连续整数索引,用索引作为矩阵下标,同时保留原ID作为矩阵的行/列名方便查看。修改后的代码如下:

create_interaction_matrices <- function(nm, behavior_code = "AFF", select_every = 10, nsel = 25) {
  NNdatafull <- read_excel(nm, sheet = 1)
  colnames(NNdatafull) <- c("Date", "Time", "Pen", "Pig_ID", "Distance", "Closest_Pig", "Behavior", "Orientation", "Location")
  datelevels <- unique(NNdatafull$Date)
  
  interaction_matrices <- list()
  
  for (date in datelevels) {
    mdat <- filter(NNdatafull, Date == date)
    mdat <- filter(mdat, Behavior == behavior_code)
    
    # 获取所有出现过的猪ID(包括Pig_ID和Closest_Pig)
    unique_pigs <- union(unique(mdat$Pig_ID), unique(mdat$Closest_Pig))
    # 创建ID到连续索引的映射:每个ID对应1、2、3...
    pig_index <- setNames(seq_along(unique_pigs), unique_pigs)
    
    # 初始化矩阵,同时给行和列命名为原猪ID
    interaction_matrix <- matrix(0, 
                                 nrow = length(unique_pigs), 
                                 ncol = length(unique_pigs),
                                 dimnames = list(unique_pigs, unique_pigs))
    
    for (i in 1:nsel) {
      time <- min(mdat$Time) + (i - 1) * (60 * select_every)
      time_data <- filter(mdat, Time == time)
      interacting_pigs <- unique(time_data$Pig_ID)
      
      # 更新交互矩阵:用映射后的索引代替原ID数值
      for (pig_id in interacting_pigs) {
        closest_pig <- time_data$Closest_Pig[time_data$Pig_ID == pig_id]
        # 通过pig_index获取对应的索引
        row_idx <- pig_index[as.character(pig_id)]
        col_idx <- pig_index[as.character(closest_pig)]
        interaction_matrix[row_idx, col_idx] <- interaction_matrix[row_idx, col_idx] + 1
      }
    }
    interaction_matrices[[as.character(date)]] <- interaction_matrix
  }
  return(interaction_matrices)
}

关键修改点说明:

  • 新增pig_index:用setNames创建一个命名向量,键是原猪ID,值是连续的整数索引(从1到length(unique_pigs))
  • 初始化矩阵时添加dimnames:把矩阵的行和列命名为原猪ID,后续查看矩阵时能直接对应到具体猪只
  • 矩阵赋值时使用row_idx和col_idx:通过pig_index把原ID转换成合法的矩阵下标,避免越界问题

这样修改后,无论猪ID是否连续,都能正确映射到矩阵的行/列,不会出现下标越界的错误,同时保留了原ID的可读性。


内容的提问来源于stack exchange,提问作者Carly O'Malley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 23:55:19