2013-04-08 77 views
1

我有R初學者,我寫了這個簡單的循環:爲什麼R中這個簡單的循環很慢?

for(i in 1:12000){ 
    if(v$piano.tariff[i] == 2) {v$piano.tariff[i] = 0} 
    else {v$piano.tariff[i] = 1} 
} 

其中V是一個數據幀和piano.tariff其列之一。循環所做的只是將piano.tariff列的每個值更改爲1或0,從它們的初始值2和5開始。

現在,代碼可以工作,但問題在於它的速度很慢。最多需要4-5分鐘才能完成!在C++中,C#這樣的循環幾乎不需要幾秒鐘。

爲什麼這麼慢?有沒有更快的方法來實現這一點?還是僅僅是R慢了,就是這樣?

+0

如果您是R的新手,很多關於循環和矢量化的問題都可以在http://www.burns-stat.com/pages/Tutor/R_inferno.pdf – 2013-04-08 16:59:32

回答

5

我想你可以在這裏嘗試一個矢量化的方法。

編輯 感謝Henrik,以前的版本有點偏離。我認爲新方法是好的。

twos <- v$piano.tariff == 2 
notwos <- v$piano.tariff != 2 
v[twos, "piano.tariff"] <- 0 
v[notwos, "piano.tariff"] <- 1 

夠快嗎? :)

+0

這是瞬間的,謝謝!我修改了一下,因爲我知道其他值是5我在第二行使用了「==」,否則正如Henrik指出的那樣,它不能正常工作。 – 2013-04-08 09:36:37

+0

@Master_T看我的編輯。 Henrik指出我的第一種方法是錯誤的。 – 2013-04-08 09:40:22

7

您可能需要使用ifelse,而不是它是一個矢量一個R函數,它會更快

ifelse(v$piano.tariff==2, 0, 1) 

既然你沒有提供reproducible example我不能標杆的服務表現。

1

一般來說,您需要小心R中的循環,但更重要的是,像v$piano.tariff[i] = v$piano.tariff[i]+1這樣的循環內的賦值會導致整個向量被重新分配。

請參閱Patrick Burns在線書籍The R Inferno關於此問題的更多詳細信息。