R 如何修改代码以提高处理速度

R 如何修改代码以提高处理速度,r,R,我必须在大型矩阵中的列之间运行类似的代码 set.seed(1) my_vector <- runif( 10000 ) my_sums <- NULL for ( l in 1:length( my_vector ) ) { current_result <- my_vector[ my_vector < runif( 1 ) ] my_sums[l] <- sum( current_result ) } head(my_sums) # [1

我必须在大型矩阵中的列之间运行类似的代码

set.seed(1)

my_vector <- runif( 10000 )

my_sums <- NULL

for ( l in 1:length( my_vector ) ) {

  current_result <- my_vector[ my_vector < runif( 1 ) ]

  my_sums[l] <- sum( current_result )

}

head(my_sums)
# [1]   21.45613 2248.31463 2650.46104   62.82708   11.11391   86.21950

关于如何提高性能有什么想法吗?

关于
sapply

temp <- sapply(seq_along(my_vector), function(l){

  current_result <- my_vector[ my_vector < runif( 1 ) ]
  my_sums[l] <- sum( current_result )

})

tempEdit:添加
sort()
将我的时间减少到0.74。在本例中,对my_vector进行排序所需的时间微不足道,但在较大/不同的数据上可能代价高昂

set.seed(1)

my_vector <- runif( 10000 )
n<-runif(10000)
my_sums <- 1:10000
system.time(my_vector<-sort(my_vector))

#user  system elapsed 
# 0       0       0 
# my_vector is now sorted.


system.time(
for ( l in 1:length( my_vector ) ) {

my_sums[l] <- sum(my_vector[my_vector < n[l]])
})

# user  system elapsed 
# 0.73    0.00    0.74 

head(my_sums)
# [1]   21.4561 2248.3146 2650.4610   62.8271   11.1139   86.2195
set.seed(1)

my_vector由于您希望在大型矩阵中的列之间应用相同的函数,因此我建议:

dt <- data.table( my_vector1 = runif( 1000000 ),
                  my_vector2 = runif( 1000000 ),
                  my_vector3 = runif( 1000000 ))

cols <- paste0(names(dt),"_csum")

setkey(dt)

dt[, (cols) := lapply (.SD, function(x)  cumsum(x) )]


> head(dt)
#>      my_vector1 my_vector2 my_vector3 my_vector1_csum my_vector2_csum my_vector3_csum
#> 1: 7.664785e-07 0.47817820  0.9008552    7.664785e-07       0.4781782       0.9008552
#> 2: 8.875504e-07 0.24142375  0.9849384    1.654029e-06       0.7196019       1.8857936
#> 3: 1.326203e-06 0.48592786  0.3791094    2.980232e-06       1.2055298       2.2649030
#> 4: 2.730172e-06 0.76847160  0.5732031    5.710404e-06       1.9740014       2.8381061
#> 5: 4.655216e-06 0.01094117  0.5120915    1.036562e-05       1.9849426       3.3501976
dt my_vector1 my_vector2 my_vector3 my_vector1_csum my_vector2_csum my_vector3_csum
#>1:7.664785e-07 0.47817820 0.9008552 7.664785e-07 0.4781782 0.9008552
#>2:8.875504e-07 0.24142375 0.9849384 1.654029e-06 0.7196019 1.8857936
#>3:1.326203e-06 0.48592786 0.3791094 2.980232e-06 1.2055298 2.2649030
#>4:2.730172e-06 0.76847160 0.5732031 5.710404e-06 1.9740014 2.8381061
#>5:4.655216e-06 0.01094117 0.5120915 1.036562e-05 1.9849426 3.3501976
此外,在识别代码中每一行的时间和内存消耗方面非常有用

在底部
R

system.time({
  set.seed(1)
  my_vector <- runif(10000)
  x <- runif(10000)
  sorted <- sort(my_vector)
  ind <- findInterval(x, sorted) + 1
  my_sums <- c(0, cumsum(sorted))[ind]
})

#   user  system elapsed 
#      0       0       0 

head(my_sums)
#[1]   21.45613 2248.31463 2650.46104   62.82708   11.11391   86.21950
system.time({
种子(1)

my_vector我通过
replicate(1e4,sum)(my_vector[my_vector
我还通过提前为
my_sums
分配正确的大小,改进了您的循环。
my_sums@antonidamico:请不要随机添加
rcpp
标记。现在删除它。如果您想在大型
矩阵中的列之间运行类似的代码,最好提供一个可重复的示例t匹配此数据结构,例如a
矩阵
数据.框架
数据.表格
您应该单击此问题的一个优秀答案旁边的复选标记,将其标记为已接受。当您这样做时,复选标记将变为绿色。向上投票也是对您在回答y时所付出的努力的赞赏我们的问题:D+1表示超快速。但是,您应该更正一个错误。
x
小于
min(my_vector)
的值将返回0的索引。子集
cumsum(排序)[ind=0]
将为这些值生成
NULL
,从而从
my\u sums
向量中删除这些值,因此该向量将比
my\u向量
短。解决方案是使用
my\u sums@dww按建议进行更正。谢谢。为什么要将
0
编辑为
-Inf
?在c中使用@dww的解决方案是正确的当
x@MattDowle,我的脑海中有
findInterval(x,c(-Inf,sorted))
。谢谢你指出。回答不错+1。这与OP中的代码行为不同的一个小问题:
DT[(x),cumsum,roll=TRUE]
返回
NA
for
x
。而OP中的
sum()
在这种情况下给出0。@dww发现得很好。通过编辑将其修复为在
my_vector
的开头包含一个0。不更改计时。@dww或者,添加最后一行
my_sums[is.na(my_sums)]=0可以避免添加前一个0。也不会更改计时。@dww因此我将其更改为另一行。
dt <- data.table( my_vector1 = runif( 1000000 ),
                  my_vector2 = runif( 1000000 ),
                  my_vector3 = runif( 1000000 ))

cols <- paste0(names(dt),"_csum")

setkey(dt)

dt[, (cols) := lapply (.SD, function(x)  cumsum(x) )]


> head(dt)
#>      my_vector1 my_vector2 my_vector3 my_vector1_csum my_vector2_csum my_vector3_csum
#> 1: 7.664785e-07 0.47817820  0.9008552    7.664785e-07       0.4781782       0.9008552
#> 2: 8.875504e-07 0.24142375  0.9849384    1.654029e-06       0.7196019       1.8857936
#> 3: 1.326203e-06 0.48592786  0.3791094    2.980232e-06       1.2055298       2.2649030
#> 4: 2.730172e-06 0.76847160  0.5732031    5.710404e-06       1.9740014       2.8381061
#> 5: 4.655216e-06 0.01094117  0.5120915    1.036562e-05       1.9849426       3.3501976
system.time({
  set.seed(1)
  my_vector <- runif(10000)
  x <- runif(10000)
  sorted <- sort(my_vector)
  ind <- findInterval(x, sorted) + 1
  my_sums <- c(0, cumsum(sorted))[ind]
})

#   user  system elapsed 
#      0       0       0 

head(my_sums)
#[1]   21.45613 2248.31463 2650.46104   62.82708   11.11391   86.21950