使用write.table写入data.table时触发cedta.R错误的排查求助
问题
执行write.table(dat,'test.txt')时触发如下错误:
Error in sc[[length(sc) - 7L]][[1L]] == "example": comparison (1) is possible only for atomic and list types
追踪栈指向cedta.R文件,相关代码流程为:用fread()读取文本文件,命名列后按条件筛选行,再尝试写入新文件,完整代码如下:
dat <- fread(ptx, skip = 10, header = FALSE) names(dat) <- c("X", "Y", "Z", "Intensity", "R", "G", "B") ptx_header = readLines(ptx,n=2) ncols = as.integer(ptx_header[1]) nrows = as.integer(ptx_header[2]) if (reducePtx==T){ # Remove every other point from PTX file npoints = dim(dat)[1] cols = 0:(npoints-1) %/% ncols rows = rep.int(0:(nrows-1),ncols) dat1 = dat[cols%%2==0 & rows%%2==0,] remove(cols) remove(rows) # Write output ptx file ptx_out = paste0('reduced_',ptx) write.table(dat1,ptx_out,append = T,sep=' ',quote=F,row.names = F,col.names = F)}
原因分析
这个错误由data.table的cedta(Caller Environment Detection Toolkit for data.table)机制触发,核心原因:
- 筛选行时使用了外部向量
cols和rows,而非data.table内部列,这种混合外部向量的筛选逻辑干扰了cedta的环境检测流程,导致类型匹配错误。 write.table是基础R函数,对data.table对象的兼容性不如data.table原生写入函数,进一步放大了该问题。
解决方法
方法1:改用data.table原生语法筛选行
将筛选逻辑移至data.table内部计算,避免外部向量引发的环境冲突:
if (reducePtx == TRUE){ npoints = nrow(dat) # 在data.table内部生成cols和rows列 dat[, `:=`(cols = 0:(.N-1) %/% ncols, rows = rep.int(0:(nrows-1), ncols))] # 筛选后移除临时列 dat1 = dat[cols%%2 == 0 & rows%%2 == 0, !c("cols", "rows")] ptx_out = paste0('reduced_',ptx) write.table(dat1, ptx_out, append = TRUE, sep=' ', quote=FALSE, row.names=FALSE, col.names=FALSE) }
方法2:使用data.table原生写入函数fwrite
fwrite是data.table专为自身对象设计的写入函数,兼容性更强且速度更快:
# 替换原write.table代码为以下内容 fwrite(dat1, ptx_out, append = TRUE, sep = " ", quote = FALSE, row.names = FALSE, col.names = FALSE)
方法3:转换为data.frame后再写入
若坚持使用write.table,可先将data.table转为普通data.frame:
write.table(as.data.frame(dat1), ptx_out, append = TRUE, sep=' ', quote=FALSE, row.names=FALSE, col.names=FALSE)
内容的提问来源于stack exchange,提问作者JT_geospatial
相关产品推荐
相关产品推荐

