我对代码做了一些改动,并增加了一些对内存地址的打印。setDT
在处理非data.table
的变量的时候会进行shallow copy。从后面打印的地址可以看到,在setDT(dt)
之后,dt
的地址变了,但是dt
内包含的变量,如TYPE
,其地址是不变的。而names(dt)
的结果,会跟着dt
进行变化。
所以第一个版本(先setDT
再setnames
)这个变量名的修改并没有能够传递到全局环境里的data1
,但是对TYPE
这一列的修改,却又体现到了全局环境的data1
里。
而对第二个版本(先setnames
再setDT
)这个变量名的修改就传递到了全局变量的data1
,但在setDT
之后,实际上函数内的dt
已经指向了一个新的地址。不过对type
的修改还是可以传递到data1
,因为他们背后是同一个地址。
另外,因为对tables
做了赋值(tables <- lapply(xxx)
),所以tables
也不是原来的tables
了,tabels$data1
也不一定是原来的tables$data1
或者data1
了
第一个版本
library(data.table)
data1 <- data.frame(TYPE = c(1:3), VALUE = c(2:4))
tables <- mget(paste0("data", c(1)))
{
print(paste0("address of `data1`: ", address(data1)))
print(paste0("address of `data1$TYPE`: ", address(data1$TYPE)))
print(paste0("address of `data1$type`: ", address(data1$type)))
print(paste0("address of `names(data1)`: ", address(names(data1))))
print(paste0("address of `tables`: ", address(tables)))
print(paste0("address of `tables$data1`: ", address(tables$data1)))
print(paste0("address of `tables$data1$TYPE`: ", address(tables$data1$TYPE)))
print(paste0("address of `tables$data1$type`: ", address(tables$data1$type)))
print(paste0("address of `names(table$data1)`: ", address(names(tables$data1))))
}
#> [1] "address of `data1`: 000001acdf8be768"
#> [1] "address of `data1$TYPE`: 000001acdf8c1968"
#> [1] "address of `data1$type`: 000001acd6e4df30"
#> [1] "address of `names(data1)`: 000001acdf8beb68"
#> [1] "address of `tables`: 000001acdfe38500"
#> [1] "address of `tables$data1`: 000001acdf8be768"
#> [1] "address of `tables$data1$TYPE`: 000001acdf8c1968"
#> [1] "address of `tables$data1$type`: 000001acd6e4df30"
#> [1] "address of `names(table$data1)`: 000001acdf8beb68"
tables <- lapply(tables, function(dt) {
print("At the beginning: ")
print(paste0("address of dt: ", address(dt)))
print(paste0("address of dt$TYPE: ", address(dt$TYPE)))
print(paste0("address of names(dt): ", address(names(dt))))
print(" ")
setDT(dt)
print("After `setDT`")
print(paste0("address of dt: ", address(dt)))
print(paste0("address of dt$TYPE: ", address(dt$TYPE)))
print(paste0("address of names(dt): ", address(names(dt))))
print(" ")
dt[, TYPE := 11]
dt[, type := 22]
print("After `setDT` + `:=`, but before `setnames`: ")
print(paste0("address of dt: ", address(dt)))
print(paste0("address of dt$TYPE: ", address(dt$TYPE)))
print(paste0("address of dt$type: ", address(dt$type)))
print(paste0("address of names(dt): ", address(names(dt))))
print(" ")
setnames(dt, new = tolower(colnames(dt)))
print("After `setnames`")
print(paste0("address of dt: ", address(dt)))
print(paste0("address of dt$TYPE: ", address(dt$TYPE)))
print(paste0("address of dt$type: ", address(dt$type)))
print(paste0("address of names(dt): ", address(names(dt))))
print(" ")
return(dt)
})
#> [1] "At the beginning: "
#> [1] "address of dt: 000001acdf8be768"
#> [1] "address of dt$TYPE: 000001acdf8c1968"
#> [1] "address of names(dt): 000001acdf8beb68"
#> [1] " "
#> [1] "After `setDT`"
#> [1] "address of dt: 000001acdc1f0e00"
#> [1] "address of dt$TYPE: 000001acdf8c1968"
#> [1] "address of names(dt): 000001acdadfb270"
#> [1] " "
#> [1] "After `setDT` + `:=`, but before `setnames`: "
#> [1] "address of dt: 000001acdc1f0e00"
#> [1] "address of dt$TYPE: 000001acdf8c1968"
#> [1] "address of dt$type: 000001ace20940e8"
#> [1] "address of names(dt): 000001acdadfb270"
#> [1] " "
#> [1] "After `setnames`"
#> [1] "address of dt: 000001acdc1f0e00"
#> [1] "address of dt$TYPE: 000001acd6e4df30"
#> [1] "address of dt$type: 000001acdf8c1968"
#> [1] "address of names(dt): 000001acdadfb270"
#> [1] " "
str(data1)
#> Classes 'data.table' and 'data.frame': 3 obs. of 2 variables:
#> $ TYPE : int 11 11 11
#> $ VALUE: int 2 3 4
{
print(paste0("address of `data1`: ", address(data1)))
print(paste0("address of `data1$TYPE`: ", address(data1$TYPE)))
print(paste0("address of `data1$type`: ", address(data1$type)))
print(paste0("address of `names(data1)`: ", address(names(data1))))
print(paste0("address of `tables`: ", address(tables)))
print(paste0("address of `tables$data1`: ", address(tables$data1)))
print(paste0("address of `tables$data1$TYPE`: ", address(tables$data1$TYPE)))
print(paste0("address of `tables$data1$type`: ", address(tables$data1$type)))
print(paste0("address of `names(table$data1)`: ", address(names(tables$data1))))
}
#> [1] "address of `data1`: 000001acdf8be768"
#> [1] "address of `data1$TYPE`: 000001acdf8c1968"
#> [1] "address of `data1$type`: 000001acd6e4df30"
#> [1] "address of `names(data1)`: 000001acdf8beb68"
#> [1] "address of `tables`: 000001acdff04f48"
#> [1] "address of `tables$data1`: 000001acdc1f0e00"
#> [1] "address of `tables$data1$TYPE`: 000001acd6e4df30"
#> [1] "address of `tables$data1$type`: 000001acdf8c1968"
#> [1] "address of `names(table$data1)`: 000001acdadfb270"
第二个版本
data1 <- data.frame(TYPE = c(1:3), VALUE = c(2:4))
tables <- mget(paste0("data", c(1)))
{
print(paste0("address of `data1`: ", address(data1)))
print(paste0("address of `data1$TYPE`: ", address(data1$TYPE)))
print(paste0("address of `data1$type`: ", address(data1$type)))
print(paste0("address of `names(data1)`: ", address(names(data1))))
print(paste0("address of `tables`: ", address(tables)))
print(paste0("address of `tables$data1`: ", address(tables$data1)))
print(paste0("address of `tables$data1$TYPE`: ", address(tables$data1$TYPE)))
print(paste0("address of `tables$data1$type`: ", address(tables$data1$type)))
print(paste0("address of `names(table$data1)`: ", address(names(tables$data1))))
}
#> [1] "address of `data1`: 000001ace29192e8"
#> [1] "address of `data1$TYPE`: 000001ace2919ba8"
#> [1] "address of `data1$type`: 000001acd6e4df30"
#> [1] "address of `names(data1)`: 000001ace29191e8"
#> [1] "address of `tables`: 000001ace2958178"
#> [1] "address of `tables$data1`: 000001ace29192e8"
#> [1] "address of `tables$data1$TYPE`: 000001ace2919ba8"
#> [1] "address of `tables$data1$type`: 000001acd6e4df30"
#> [1] "address of `names(table$data1)`: 000001ace29191e8"
tables <- lapply(tables, function(dt) {
print("At the beginning: ")
print(paste0("address of dt: ", address(dt)))
print(paste0("address of dt$TYPE: ", address(dt$TYPE)))
print(paste0("address of names(dt): ", address(names(dt))))
print(" ")
setnames(dt, new = tolower(colnames(dt)))
print("After `setnames`")
print(paste0("address of dt: ", address(dt)))
print(paste0("address of dt$TYPE: ", address(dt$TYPE)))
print(paste0("address of dt$type: ", address(dt$type)))
print(paste0("address of names(dt): ", address(names(dt))))
print(" ")
setDT(dt)
print("After `setDT`")
print(paste0("address of dt: ", address(dt)))
print(paste0("address of dt$TYPE: ", address(dt$TYPE)))
print(paste0("address of dt$type: ", address(dt$type)))
print(paste0("address of names(dt): ", address(names(dt))))
print(" ")
dt[, TYPE := 11]
dt[, type := 22]
print("After `setDT` + `:=`: ")
print(paste0("address of dt: ", address(dt)))
print(paste0("address of dt$TYPE: ", address(dt$TYPE)))
print(paste0("address of dt$type: ", address(dt$type)))
print(paste0("address of names(dt): ", address(names(dt))))
print(" ")
return(dt)
})
#> [1] "At the beginning: "
#> [1] "address of dt: 000001ace29192e8"
#> [1] "address of dt$TYPE: 000001ace2919ba8"
#> [1] "address of names(dt): 000001ace29191e8"
#> [1] " "
#> [1] "After `setnames`"
#> [1] "address of dt: 000001ace29192e8"
#> [1] "address of dt$TYPE: 000001acd6e4df30"
#> [1] "address of dt$type: 000001ace2919ba8"
#> [1] "address of names(dt): 000001ace29191e8"
#> [1] " "
#> [1] "After `setDT`"
#> [1] "address of dt: 000001acdacedb60"
#> [1] "address of dt$TYPE: 000001acd6e4df30"
#> [1] "address of dt$type: 000001ace2919ba8"
#> [1] "address of names(dt): 000001acdf5c5040"
#> [1] " "
#> [1] "After `setDT` + `:=`: "
#> [1] "address of dt: 000001acdacedb60"
#> [1] "address of dt$TYPE: 000001ace3a1ccc8"
#> [1] "address of dt$type: 000001ace2919ba8"
#> [1] "address of names(dt): 000001acdf5c5040"
#> [1] " "
str(data1)
#> Classes 'data.table' and 'data.frame': 3 obs. of 2 variables:
#> $ type : int 22 22 22
#> $ value: int 2 3 4
{
print(paste0("address of `data1`: ", address(data1)))
print(paste0("address of `data1$TYPE`: ", address(data1$TYPE)))
print(paste0("address of `data1$type`: ", address(data1$type)))
print(paste0("address of `names(data1)`: ", address(names(data1))))
print(paste0("address of `tables`: ", address(tables)))
print(paste0("address of `tables$data1`: ", address(tables$data1)))
print(paste0("address of `tables$data1$TYPE`: ", address(tables$data1$TYPE)))
print(paste0("address of `tables$data1$type`: ", address(tables$data1$type)))
print(paste0("address of `names(table$data1)`: ", address(names(tables$data1))))
}
#> [1] "address of `data1`: 000001ace29192e8"
#> [1] "address of `data1$TYPE`: 000001acd6e4df30"
#> [1] "address of `data1$type`: 000001ace2919ba8"
#> [1] "address of `names(data1)`: 000001ace29191e8"
#> [1] "address of `tables`: 000001ace2a2b3c0"
#> [1] "address of `tables$data1`: 000001acdacedb60"
#> [1] "address of `tables$data1$TYPE`: 000001ace3a1ccc8"
#> [1] "address of `tables$data1$type`: 000001ace2919ba8"
#> [1] "address of `names(table$data1)`: 000001acdf5c5040"
<sup>Created on 2025-04-08 with reprex v2.1.1</sup>