R data.table循环赋值语法不一致,求原因及正确实现方式
data.table循环中的语法不一致问题解析与正确写法
语法不一致的原因
关于DT[2, ..i]
..i是data.table特有的上层环境变量引用语法,作用是把循环变量i对应的列位置映射为实际列,所以print(DT[2, ..i])能正常输出第2行第i列的值。但DT[2, ..i] <- 45报错,是因为这种直接赋值的写法属于R基础子集操作,并不兼容data.table的..前缀语法——data.table的原地修改必须用:=操作符,而非<-,这两种赋值逻辑的解析规则完全不同。
关于DT[2, i]
在data.table的查询语法里,第二位置参数默认是j(列操作),直接写i会被当成列名查询,但循环中i是数字(1/2/3),DT里没有对应列名,所以print(DT[2, i])报错。但DT[2, i] <- 45是R基础的矩阵式位置赋值,此时R会把DT当成普通数据框/矩阵,按“行2,列i”的位置直接修改值,这是R基础语法的行为,和data.table的语法逻辑不冲突,所以能正常运行。
循环的正确编码方式
要统一遵循data.table的语法规范(保证效率和一致性),推荐用:=操作符实现原地修改,以下是两种可靠写法:
写法1:通过列名映射赋值
library(data.table) DT <- data.table(x = 1:5, y = 6:10, z = 11:15) DT for(i in 1:3){ # 打印目标值 print(DT[2, ..i]) # 用:=原地修改,通过i获取列名 DT[2, (colnames(DT)[i]) := 45] }
写法2:结合.SDcols指定列
library(data.table) DT <- data.table(x = 1:5, y = 6:10, z = 11:15) DT for(i in 1:3){ print(DT[2, ..i]) # 用.SDcols指定要操作的列,再通过:=修改 DT[2, .SDcols = i, (colnames(DT)[i]) := 45] }
如果只是追求简洁,也可以直接用R基础的位置赋值DT[2, i] <- 45,但这种写法没有利用data.table的原地修改优势,当处理大数据集时效率会低于:=写法。
内容的提问来源于stack exchange,提问作者Bertrand
相关产品推荐
相关产品推荐

