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

dplyr mutate报invalid 'length' argument错误及结果异常求解

问题描述

运行可复现代码时,执行到计算ClassDecrease字段的最后一段mutate语句前所有逻辑均可正常运行,执行该语句时会触发invalid 'length' argument报错,且输出结果不符合预期:

  • ClassDecrease字段预期输出:
0
0
0
0
0
-1
  • 当前实际输出:
0
0
0
0
1
1

完整问题复现代码如下:

library(dplyr)

data <- 
  data.frame(
    Element = c("D","D","R","D","C","C"),
    SplitCode = c(0,0,0,0,1,1)
  )


Class_to_Count <- 1

excelCopy <- data %>% 
  group_by(Element) %>% 
  mutate(PreSplitClass = row_number()) %>% 
  ungroup() %>%
  mutate(ClassAtSplit =
           case_when(
             SplitCode == 0 ~ as.integer(0), # This eliminates checking for > 0
             SplitCode > lag(SplitCode) ~ PreSplitClass, # if > previous value
             SplitCode == lag(SplitCode) ~ lag(PreSplitClass) # if equal (0s are avoided)
           )
  ) %>%
  mutate(
    LowClassSplit =
      case_when(
        SplitCode > lag(SplitCode) & SplitCode == Class_to_Count ~ PreSplitClass,
        SplitCode == lag(SplitCode) & SplitCode == Class_to_Count ~ lag(PreSplitClass),
        TRUE ~ 0L
      )
  ) %>%
  mutate(
    GrossSubclass =
      case_when(
        LowClassSplit == Class_to_Count ~ PreSplitClass,
        TRUE ~ 0L
      )
    ) %>%
  group_by(Element) %>% 
  mutate(NetSubclass = cumsum(LowClassSplit == Class_to_Count)
         ) %>%
  
  ungroup %>%
  
  rowwise() %>% 
    mutate(
      ClassSubclass = sum(LowClassSplit, NetSubclass/10)
    ) %>%
  
  ungroup %>%
  
  mutate(ApplyToNoSplits = ClassSubclass[match(PreSplitClass, GrossSubclass)] * !SplitCode) %>%
  
  ungroup %>%
  
  # 报错位置
  mutate(ClassDecrease = 
           case_when(
            LowClassSplit == Class_to_Count ~ (integer(trunc(ClassSubclass)) - PreSplitClass),
            TRUE ~ 0L
           )
         )
  
  print.data.frame(excelCopy)
问题原因

报错和结果偏差的核心是误用了R的integer()函数:

  • integer(n)的作用是生成长度为n、元素全为0的整数向量,要求传入的参数是合法的向量长度值
  • 代码中写的integer(trunc(ClassSubclass)),相当于把trunc(ClassSubclass)的计算结果作为向量长度传入,当传入值不符合长度参数要求时就会触发长度参数无效报错,计算逻辑也完全偏离预期
    此处实际需求是将trunc(ClassSubclass)的计算结果转换为整数类型,应该使用as.integer()函数而非integer()。
修复方案

将计算ClassDecrease部分的integer()替换为as.integer()即可,修改后的对应代码段如下:

mutate(ClassDecrease = 
         case_when(
          LowClassSplit == Class_to_Count ~ (as.integer(trunc(ClassSubclass)) - PreSplitClass),
          TRUE ~ 0L
         )
       )

替换后运行代码不会触发报错,ClassDecrease字段输出和预期完全一致。

内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:03:26