Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有一种更快的方式来运行嵌套在两个for循环中的sapply?_R_For Loop_Sapply - Fatal编程技术网

有没有一种更快的方式来运行嵌套在两个for循环中的sapply?

有没有一种更快的方式来运行嵌套在两个for循环中的sapply?,r,for-loop,sapply,R,For Loop,Sapply,我有一个大数据框架,上面有超过100万行表示几个个体的时间序列数据(在不同的列中有不同的个体数据)。 此外,我还有一个3D数组,其中包含“遭遇”帧编号,指示我要从时间序列中的哪个帧提取数据 对于给定的个人和遭遇类型,我想提取一个时间序列,例如100帧。但是,由于我对每种会议类型和每一个人都有许多重复,所以我想直接计算每一个人和每一次会面类型的平均时间序列 我设法做到这一点,使用sapply嵌入在两个for循环中。然而,运行这些for循环非常慢,我现在想知道在R中是否有更快的方法来实现这个计算,或

我有一个大数据框架,上面有超过100万行表示几个个体的时间序列数据(在不同的列中有不同的个体数据)。 此外,我还有一个3D数组,其中包含“遭遇”帧编号,指示我要从时间序列中的哪个帧提取数据

对于给定的个人和遭遇类型,我想提取一个时间序列,例如100帧。但是,由于我对每种会议类型和每一个人都有许多重复,所以我想直接计算每一个人和每一次会面类型的平均时间序列

我设法做到这一点,使用sapply嵌入在两个for循环中。然而,运行这些for循环非常慢,我现在想知道在R中是否有更快的方法来实现这个计算,或者我是否应该在C++中实现。下面是我的代码和我的一小部分数据:

nb_ind = 3;
response_duration = 100;
nb_meeting_types = 2;
nb_variables = 2;
speed_offset = 2;
MEETING_START_OFFSET = 50;
replicate = 20;

# behavior_data is a data frame with columns: frame,speed1,head1,speed2,head2,speed3,head3
# there are about 1 million rows
dim(behavior_data)
[1] 1080000  7

head(behavior_data)
  frame speed1 head1 speed2 headd2 speed3 head3 
1  0      0     25    2.4   179     1.1   16
2  1      1.5   20    2.0   -175    1.6   27
3  2      1.6   28    2.0   -178    1.0   37
4  3      0.8   56    1.6   170     0.8   37
5  4      0.3   56    1.8   162     0     40

# encounters is an array with frame numbers of dimension [nb_ind,replicate,nb_meeting_types]
# these frame number correspond to starting points of meetings, for which I want to calculate the speed    
dim(encounters)
[1] 3 20  2

head(encounters[,,1])
    [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]  [,11] [,12]  [,13]  [,14] [,15]  [,16] [,17]  [,18]  [,19] [,20]
[1,] 12049 17693 23350 29018 34666 40327 68608 57293 74264 45980 113864 79922 119522 102552 51636 153462 91235 142151 159121 62948
[2,] 12036 17694 23352 29014 34674 40322 68606 57296 74268 45982 113865 79929 119521 102558 51639 153463 91242 142161 159168 62952
[3,] 12037 17694 23351 29011 34669 40329 68606 57298 74263 45985     NA 79921     NA 102550 51641     NA 91234     NA     NA 62950


all_average_speeds = array(NaN, c(nb_ind, response_duration, nb_meeting_types))
for (j in 1:nb_ind){

  #calculate the average speed response for each meeting type for a given individual
  average_speed = numeric(0);
  for (i in 1:nb_meeting_types){

    # calculate the average speed response across all replicates of a given meeting type for a given individual
average_speed_type = sapply(1:response_duration, function(k){
      mean(behavior_data[,(j-1)*nb_variables + speed_offset][which(behavior_data$frame == ((encounters[j,,i] + k-1) - MEETING_START_OFFSET)], na.rm=TRUE)
    })
    average_speed = rbind(average_speed, t(average_speed_type))
  }
  all_average_speeds[j,,] = average_speed; 
}

从第一眼看,我无意中发现了内部循环中的rbind。这通常是个坏主意。尝试提前分配平均速度将拥有的所有内存和所有列和行(找到比
average\u speed=numeric(0);
)更好的内存和列,然后查看是否足够快。如果没有,请触摸工作回路。如果需要对循环进行一些尝试,请尝试外部循环的
foreach
包中的
foreach
循环。它使从
循环到并行处理变得非常容易。请包含代码使用的数据集-更改数字使其匹配,或者在此处放置更大的部分。这可能是完全矢量化的,我能看到的Other快速加速如果“frame”列等于行号,你可以用位置子集替换sapply。@Bernhard。按照建议,我替换了
平均速度=数值(0)
使用预分配数组填充NaN,但在执行时间方面没有差异。对于我的部分数据集(15个人,时间序列为1090504帧,响应持续时间为1200帧,5种会议类型),当我使用数字时,时间为23.91分钟,当我使用预分配数组时,时间为23.94分钟。@jeremycg。我不明白你关于使用子集的建议。你能提供更多的细节吗。对于info,帧编号并不总是等于行编号,但由于帧编号是连续的且不断增加,因此偏移应该能够解释差异。另外,我的数据集似乎太大(450MB),无法上传到这里。为了进一步增加性能问题,我测试了代码,在嵌套for循环中添加了另一个sappy,执行代码所需的时间增加了一倍,这表明是sappy本身消耗了时间。如果我自己运行sapply,即通过设置I=1和j=1,则需要大约4.28分钟。有没有比我选择的更有效的方法来编写sappy函数?