使用整数变量筛选data.table行失效问题求助
data.table循环筛选失效问题解决
问题根源
循环变量y和数据表v中的坐标列y重名了。data.table在筛选表达式(i参数)中会优先引用数据表内部的列,所以year==y里的y实际指向的是坐标列,而非循环变量y,导致筛选条件完全错误,自然查不到匹配的行。
解决方法
有两种可行的解决思路:
- 重命名循环变量,避免和数据表列名冲突(推荐,代码可读性更高)
- 明确指定循环变量来自全局环境,绕过data.table的列优先引用规则
修正后的代码
方法1:修改循环变量名
library(data.table) set.seed(21) v <- data.table(dt=sample(seq(as.Date('2010/01/01'), as.Date('2020/12/31'), by="day"), 50), x=sample(seq(100,600),50), y=sample(seq(0,1000),50)) v[ ,year:=as.integer(format(dt, "%Y"))] v[ ,mon:=as.integer(format(dt, "%m"))] v[ ,day:=as.integer(format(dt, "%d"))] # 将循环变量y改为yr,m改为mo,避免和列名冲突 for(yr in min(v$year):max(v$year)){ for(mo in 1:12){ x <- v[year==yr & mon==mo, ] if(nrow(x)>0){ print(paste(yr, mo, nrow(x))) } } }
方法2:明确引用全局环境变量
library(data.table) set.seed(21) v <- data.table(dt=sample(seq(as.Date('2010/01/01'), as.Date('2020/12/31'), by="day"), 50), x=sample(seq(100,600),50), y=sample(seq(0,1000),50)) v[ ,year:=as.integer(format(dt, "%Y"))] v[ ,mon:=as.integer(format(dt, "%m"))] v[ ,day:=as.integer(format(dt, "%d"))] for(y in min(v$year):max(v$year)){ for(m in 1:12){ # 用.GlobalEnv$指定使用全局环境中的循环变量 x <- v[year==.GlobalEnv$y & mon==.GlobalEnv$m, ] if(nrow(x)>0){ print(paste(y, m, nrow(x))) } } }
验证效果
运行修正后的代码,会输出对应年月的记录数,比如:
[1] "2010 3 1" [1] "2010 5 1" [1] "2010 7 1" [1] "2010 10 1" [1] "2011 2 1" ...
手动测试也能得到正确结果:
> yr<-2020 > mo<-9 > nrow(v[year==yr & mon==mo, ]) [1] 2
内容的提问来源于stack exchange,提问作者Stuart Ball
相关产品推荐
相关产品推荐

