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

循环索引值指定错误修复:index_1_i:index_2_i出现NA/NaN参数错误

问题描述

我尝试将数据集拆分为非重叠块,对每个块执行操作(如列乘以100)并保存结果。示例数据:

my_data = data.frame(id = 1:837, a = rnorm(837,100,100), b = rnorm(837,100,100), c = rnorm(837,100,100))

我想将其拆分为10个块:

res = round(seq(1, 837, by = 837/10))[-1]
# [1]  85 168 252 336 420 503 587 671 754

res <- append(res, 1, after=0)
res <- append(res, 837, after=10)
# [1]   1  85 168 252 336 420 503 587 671 754 837

目标拆分方式:

  • data_1 : id = 1 至 id = 84
  • data_2: id = 85 至 id = 168
  • data_3: id = 169 至 id = 251
  • data_4 : id = 252 至 id = 335
  • 以此类推

我编写了如下循环实现该过程:

for (i in 1:length(res))
{
  index_1_i = res[i]
  index_2_i = res[i+1]
  
  data_i = my_data[index_1_i : index_2_i,]
  
  data_i$a = data_i$a*100
  data_i$b = data_i$b*100 - data_i$a*100
  data_i$c = data_i$c*100 - data_i$b
  
  # 保存时文件名出现多余空格(例如"data_ 10.csv")
  write.csv(data_i,  paste("data_", i, ".csv")) 
  
  # 希望从R环境中删除对象以避免占用内存
  data_i = NULL
}

运行时出现错误:Error in index_1_i:index_2_i : NA/NaN argument


错误原因与修复方案

1. 循环边界越界(核心错误)

res向量长度是11,你循环时i从1到11,当i=11时,res[i+1]会调用res[12],超出向量范围返回NA,导致索引切片时出现无效参数。

修复:把循环范围改成1:(length(res)-1),这样i最大到10,res[i+1]刚好取到res[11](即837),不会越界。

2. 索引范围不符合目标拆分逻辑

当前代码里my_data[index_1_i : index_2_i,]会把第一个块变成1到85,但你要的是1到84。需要调整索引规则:

  • 前9个块的结束索引是res[i+1]-1
  • 最后一个块直接用res[i+1](避免把最后一行id=837漏掉)

修复:在循环里加判断逻辑:

if (i == length(res)-1) {
  data_i = my_data[index_1_i : index_2_i,]
} else {
  data_i = my_data[index_1_i : (index_2_i - 1),]
}

3. 文件名多余空格问题

paste("data_", i, ".csv")会自动在参数间加空格,改用paste0(无分隔符拼接)或者指定sep=""即可解决:

write.csv(data_i, paste0("data_", i, ".csv"))
# 或者
write.csv(data_i, paste("data_", i, ".csv", sep=""))

4. 内存清理优化

赋值data_i = NULL可以,但用rm(data_i)更彻底,配合gc()触发垃圾回收(可选,内存紧张时推荐)。


修复后的完整代码
my_data = data.frame(id = 1:837, a = rnorm(837,100,100), b = rnorm(837,100,100), c = rnorm(837,100,100))

res = round(seq(1, 837, by = 837/10))[-1]
res <- append(res, 1, after=0)
res <- append(res, 837, after=10)

# 修正循环范围
for (i in 1:(length(res)-1)) {
  index_1_i = res[i]
  index_2_i = res[i+1]
  
  # 调整索引匹配目标拆分
  if (i == length(res)-1) {
    data_i = my_data[index_1_i : index_2_i,]
  } else {
    data_i = my_data[index_1_i : (index_2_i - 1),]
  }
  
  # 执行数据操作
  data_i$a = data_i$a * 100
  data_i$b = data_i$b * 100 - data_i$a * 100
  data_i$c = data_i$c * 100 - data_i$b
  
  # 生成无空格的文件名并保存
  write.csv(data_i, paste0("data_", i, ".csv"), row.names = FALSE)
  
  # 清理内存
  rm(data_i)
  gc()
}

额外优化建议

不想手动处理索引的话,可以用cut()生成分组标签,再用split()自动拆分,代码更简洁:

# 生成10个分组的标签
my_data$group = cut(my_data$id, breaks = res, labels = 1:10, include.lowest = TRUE)
# 自动拆分数据为列表
data_list = split(my_data, my_data$group)

# 遍历列表处理并保存
for (i in 1:length(data_list)) {
  df = data_list[[i]]
  df$a = df$a * 100
  df$b = df$b * 100 - df$a * 100
  df$c = df$c * 100 - df$b
  write.csv(df, paste0("data_", i, ".csv"), row.names = FALSE)
  rm(df)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:39:19