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

在R中对分组海洋光剖面数据执行暗信号识别的问题

问题描述

我正在研究海洋下行光剖面,尝试实现文献中的“暗信号识别”流程:

  • 数据按Profile分组,每个分组用Lillifors检验判断light值是否符合正态分布
  • 若不符合,移除该组内最浅深度的点并重复检验,直到通过正态性检验
  • 剩余点标记为'dark',被移除的点标记为'light'

编写测试代码后,针对单个profile测试的循环代码运行报错:

Error in UseMethod("mutate") :
no applicable method for 'mutate' applied to an object of class "logical"

测试代码如下:

library(nortest)
library(dplyr)

# test dataset
profile = c(1)
depth = seq(1,250,1)
PAR = seq(10,1,along.with = depth)
PAR <- log(PAR) # 模拟光随深度的指数变化

p1 <- data.frame(profile = profile,
                   depth = depth,
                   PAR = PAR)

profile = c(2)
p2 <- data.frame(profile = profile,
                 depth = depth,
                 PAR = PAR)

data <- rbind(p1,p2)

p1[ , 'signal'] = NA

单个profile测试的循环代码:

for (i in p1) {
  ltest <- lillie.test(p1$PAR)
  if (ltest$p.value < 0.01) {
    p1 <- mutate(p1$signal == "light")
    p1 <- filter(p1, depth != min(depth))
  } else if (ltest$p.value > 0.01) {
    p1 <- mutate(p1$signal == "dark" )
  }
}
错误原因
  1. mutate语法错误:mutate(p1$signal == "light")是错误用法,mutate要求第一个参数是数据框,后续是列名 = 值的赋值逻辑,你直接传入了逻辑向量,导致函数无法识别对象类型。
  2. 循环逻辑错误:for (i in p1)会遍历数据框的每一列,完全不符合需求;且每次移除最浅点后,没有用剩余数据重新检验,而是一直基于原始数据判断。
  3. 标记逻辑错误:你直接过滤掉了要标记为"light"的点,丢失了这些点的标记信息,正确逻辑应该是保留所有点并分别标记。
修正后的代码

单个Profile的处理逻辑

library(nortest)
library(dplyr)

# 复制原始数据,避免修改原数据
p1_processed <- p1 %>% mutate(signal = NA_character_)

# 循环进行Lillifors检验,直到通过或只剩一个点
while(nrow(p1_processed) > 1) {
  # 取当前未标记的数据做检验
  current_par <- p1_processed$PAR[is.na(p1_processed$signal)]
  ltest <- lillie.test(current_par)
  
  if(ltest$p.value >= 0.01) {
    # 通过检验,剩余未标记点标记为dark
    p1_processed <- p1_processed %>% 
      mutate(signal = ifelse(is.na(signal), "dark", signal))
    break
  } else {
    # 未通过,找到当前未标记数据中最浅的深度,标记为light
    min_depth <- min(p1_processed$depth[is.na(p1_processed$signal)])
    p1_processed <- p1_processed %>% 
      mutate(signal = ifelse(depth == min_depth & is.na(signal), "light", signal))
  }
}

# 处理只剩最后一个点的情况
if(nrow(p1_processed) == 1 && is.na(p1_processed$signal)) {
  p1_processed$signal <- "dark"
}

多Profile批量处理

把单个Profile的逻辑封装成函数,用group_modify实现分组批量处理:

# 定义单个分组的处理函数
process_profile <- function(df) {
  df <- df %>% mutate(signal = NA_character_)
  
  while(nrow(df) > 1) {
    current_par <- df$PAR[is.na(df$signal)]
    ltest <- lillie.test(current_par)
    
    if(ltest$p.value >= 0.01) {
      df <- df %>% mutate(signal = ifelse(is.na(signal), "dark", signal))
      break
    } else {
      min_depth <- min(df$depth[is.na(df$signal)])
      df <- df %>% mutate(signal = ifelse(depth == min_depth & is.na(signal), "light", signal))
    }
  }
  
  if(nrow(df) == 1 && is.na(df$signal)) {
    df$signal <- "dark"
  }
  
  return(df)
}

# 对所有Profile分组处理
data_processed <- data %>% 
  group_by(profile) %>% 
  group_modify(~process_profile(.x)) %>% 
  ungroup()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:39:50