的我試圖一個載體複製到另一個使用的語法如下:有效利用向量
data<-NULL
for(i in 1:nrow(line)){
data=append(data,line[i*4])
}
從我所看到的,在大量的數據複製使用這種方式的結果append
,這使得R非常緩慢。考慮到您從中複製的列表具有給定的大小,將一個數組的第四個元素複製到另一個數組的第四個元素的語法是什麼?
的我試圖一個載體複製到另一個使用的語法如下:有效利用向量
data<-NULL
for(i in 1:nrow(line)){
data=append(data,line[i*4])
}
從我所看到的,在大量的數據複製使用這種方式的結果append
,這使得R非常緩慢。考慮到您從中複製的列表具有給定的大小,將一個數組的第四個元素複製到另一個數組的第四個元素的語法是什麼?
這裏有三個方法與他們的基準。你可以看到,在method2
函數中預分配矢量的速度比較快,而lapply方法是中等的,而你的函數是最慢的。
當然,這些是一維向量,而不是n-D陣列,但我預計基準會相似或更明顯。
method1 <- function(line) {
data<-NULL
for(i in 1:length(line)){
data=append(data,line[i])
}
}
method2 <- function(line) {
data <- vector(mode="numeric", length = length(line))
for (i in 1:length(line)) {
data[i] <- line[i]
}
}
library(microbenchmark)
r <- rnorm(1000)
microbenchmark(method2(r), unit="ms")
#> Unit: milliseconds
#> expr min lq mean median uq max neval
#> method2(r) 2.18085 2.279676 2.428731 2.371593 2.500495 5.24888 100
microbenchmark(lapply(r, function(x) { data<-append(data, x) }), unit="ms")
#> Unit: milliseconds
#> expr min lq
#> lapply(r, function(x) { data <- append(data, x) }) 3.014673 3.091299
#> mean median uq max neval
#> 3.287216 3.150052 3.260199 6.036501 100
microbenchmark(method1(r), unit="ms")
#> Unit: milliseconds
#> expr min lq mean median uq max neval
#> method1(r) 3.938684 3.978002 5.71831 4.020001 4.280521 98.58584 100
沒有意識到OP只想每四分之一。爲什麼不使用數據框或data.table?
d <- data.frame(matrix(rnorm(1000), ncol=1))
microbenchmark(d2 <- d[seq(1,nrow(d), 4),])
#> Unit: microseconds
#> expr min lq mean median uq
#> d2 <- d[seq(1, nrow(d), 4), ] 64.846 65.9915 73.08007 67.225 73.8225
#> max neval
#> 220.438 100
library(data.table)
dt <- data.table(d)
microbenchmark(d2 <- dt[seq(1,nrow(d), 4),])
#> Unit: microseconds
#> expr min lq mean median uq
#> d2 <- dt[seq(1, nrow(d), 4), ] 298.163 315.2025 324.8793 320.554 330.416
#> max neval
#> 655.124 100
如果你想每四個元素從向量提取,你可以使用索引來seq
搶正確的元素:如您在您的問題顯示
data <- letters[seq(4, length(letters), by=4)]
data
# [1] "d" "h" "l" "p" "t" "x"
在我成長的一個載體將速度較慢,因爲您需要繼續重新分配矢量(有關詳細信息,請參閱The R Inferno的第二個圓圈)。然而,與在單個矢量化索引操作中構建矢量相比,即使預先分配矢量並使用for循環構建該矢量也會很慢。
要獲得的速度提高意識,考慮一個比較排序你所描述的方法,但是使用了預分配:
for.prealloc <- function(x) {
data <- vector(mode="numeric", length = floor(length(x)/4))
for (i in 1:floor(length(x)/4)) {
data[i] <- x[i*4]
}
data
}
josilber <- function(x) x[seq(4, length(x), by=4)]
r <- rnorm(10000)
all.equal(for.prealloc(r), josilber(r))
# [1] TRUE
library(microbenchmark)
microbenchmark(for.prealloc(r), josilber(r))
# Unit: microseconds
# expr min lq mean median uq max neval
# for.prealloc(r) 1846.014 2035.7890 2351.9681 2094.804 2244.56 5283.285 100
# josilber(r) 95.757 97.4125 125.9877 113.179 138.96 259.606 100
我建議這種方法比使用for
快20倍,一個預先分配的向量(它將比使用append
和一個非預先分配的向量更快)。
最好的方法是預先分配一個「out」向量並複製那裏的所有內容。 –
目前還不清楚你在問什麼。難道你不能創建一個索引向量,說'j'並將其用於子集你的向量'線'?然後執行'data < - line [j]'。 – 2015-10-15 05:27:42
做一個可重現的例子,包括你想要的輸出。 – Frank