我在 R 中觀察到 data.frame 修改效率的以下差異:
microbenchmark::microbenchmark(
mtcars$mpg[1] <- 0,
mtcars[["mpg"]][1] <- 0,
mtcars[1,"mpg"] <- 0
)
Unit: microseconds
expr min lq mean median uq max neval
mtcars$mpg[1] <- 0 4.400 4.801 5.16010 5.0020 5.3005 14.001 100
mtcars[["mpg"]][1] <- 0 9.600 10.201 11.08797 10.5010 10.8015 61.001 100
mtcars[1, "mpg"] <- 0 12.702 13.451 14.28102 13.8015 14.1020 47.701 100
此外,第一種方法 with$似乎比[[and好得多[,后者似乎在線性時間內起作用。
f <- function(nrow){
df <- mtcars[sample(1:32,nrow,TRUE), ]
microbenchmark::microbenchmark(
df$mpg[1] <- 0,
df[["mpg"]][1] <- 0,
df[1,"mpg"] <- 0
)
}
> f(1e5)
Unit: microseconds
expr min lq mean median uq max neval
df$mpg[1] <- 0 4.801 5.7505 41.92301 6.5505 12.2515 253.501 100
df[["mpg"]][1] <- 0 140.401 146.4510 162.82191 154.8005 165.3005 267.400 100
df[1, "mpg"] <- 0 144.801 151.5005 167.17197 159.9010 171.7010 277.102 100
> f(1e6)
Unit: microseconds
expr min lq mean median uq max neval
df$mpg[1] <- 0 5.601 10.551 733.995 18.251 918.6015 36519.5 100
df[["mpg"]][1] <- 0 908.402 1013.052 2420.035 1278.751 1704.5505 52940.7 100
df[1, "mpg"] <- 0 846.401 1018.101 2356.817 1332.900 1628.1510 57710.4 100
是什么驅動了這種行為?我讀過的大多數 R 文本似乎都被視為可互換的mtcars$mpg,mtcars[["mpg"]]因此它們以不同方式修改的事實非常令人困惑。
編輯:我根據下面 Karolis 的回答運行了一個快速基準測驗。該方法[[.data.frame似乎是罪魁禍首。如果data.frame被強制轉換,性能是可比的list。
> mtlist <- as.list(mtcars)
> microbenchmark::microbenchmark(
mtlist$mpg[1] <- 1,
mtlist[["mpg"]][1] <- 1
)
Unit: nanoseconds
expr min lq mean median uq max neval
mtlist$mpg[1] <- 1 801 900 1045.96 901 1051.0 5501 100
mtlist[["mpg"]][1] <- 1 701 801 1191.16 851 951.5 19401 100
uj5u.com熱心網友回復:
沒有$.data.frame運算子 - 因此使用$for 串列代替。
`$.data.frame`
Error: object '$.data.frame' not found
雖然[.data.frame, 和[[.data.frame都是用 R 代碼實作的函式。
`[.data.frame`
function...
`[[.data.frame`
function...
您還可以閱讀以下內容help('[.data.frame'):
> [...] There is no ‘data.frame’ method for ‘$’, so ‘x$name’ uses the
default method which treats ‘x’ as a list [...]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/435993.html
