2016-04-15 80 views
0

stu.csv包含850,000行和3列。第二列是ID的經度,第三列是ID的緯度。 stu.csv文件中的數據如下:R代碼運行速度太慢,如何加速和重寫此代碼

ID longitude latitude 
    156 41.88367183 12.48777756 
    187 41.92854333 12.46903667 
    297 41.89106861 12.49270456 
    89 41.79317669 12.43212196 
    79 41.90027472 12.46274618 
    ...  ...   ... 

該僞代碼如下。它的目的是計算與經度和緯度的地球表面上的兩個ID之間的距離,以及從任何兩個ID輸出的累積和:

dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2 
    c = 2 * atan2(sqrt(a), sqrt(1-a)) 
    distance = 6371000 * c (where 6371000 is the radius of the Earth) 

此代碼如下,但它運行太慢。如何加速和重寫代碼?謝謝。

stu<-read.table("stu.csv",header=T,sep=","); 

    ## stu has 850,000 rows and 3 columns. 

    m<-nrow(stu); 

    distance<-0; 

    for (i in 1:(m-1)) 
    { 
     for (j in (i+1)) 
     {  
     dlon = stu[j,2] - stu[i,2]; 
     dlat = stu[j,3] - stu[i,3]; 
     a = (sin(dlat/2))^2 + cos(stu[i,3]) * cos(stu[j,3]) * (sin(dlon/2))^2; 
     c = 2 * atan2(sqrt(a), sqrt(1-a)); 
     distance <-distance+6371000 * c; 
     } 
    } 

    distance 
+3

一個O上約0.4秒(N^2)算法總是要當N = 850000 .... –

+0

@ chinsoon12感謝您花很長的時間你的回覆。我描述了問題 – user2405694

+0

@ chinsoon12是 – user2405694

回答

1

對於你的情況,如果是累計距離,我們可以向量化:

x <- read.table(text = "ID longitude latitude 
156 41.88367183 12.48777756 
187 41.92854333 12.46903667 
297 41.89106861 12.49270456 
89 41.79317669 12.43212196 
79 41.90027472 12.46274618", header= TRUE) 


x$laglon <- dplyr::lead(x$longitude, 1) 
x$laglat <- dplyr::lead(x$latitude, 1) 


distfunc <- function(long, lat, newlong, newlat){ 
    dlon = newlong - long 
    dlat = newlat - lat 
    a = (sin(dlat/2))^2 + cos(lat) * cos(newlat) * (sin(dlon/2))^2 
    c = 2 * atan2(sqrt(a), sqrt(1-a)) 
    6371000 * c 
} 

distfunc(x$longitude, x$latitude, x$laglon, x$laglat) 
308784.6 281639.6 730496.0 705004.2  NA 

就拿輸出的cumsum得到總距離。

上萬行,它需要我的系統

+0

如何解決這個錯誤? http://stackoverflow.com/questions/36744127/an-error-about-vectorization-in-r – user2405694

-1

你在找什麼叫做「向量化循環」。請參閱this related question

其基本思想是在一個循環中,CPU必須在移動到第二個單元之前完成處理第一個單元,除非它有一定的保證,第一個單元的處理方式不會影響第二個小區。但是,如果它是矢量計算,那麼這個保證就存在了,並且它可以儘可能多地同時工作,從而加快速度。 (還有其他一些原因,爲什麼這個效果更好,但這是基本動機。)

請參閱this introductionapply在R中,瞭解如何在沒有循環的情況下重寫代碼。 (大部分計算的,你應該能夠保持原樣)