2013-03-05 80 views
-1

在大型數據框(100萬行+)中,我計算了特定範圍內滿足第三個條件的元素(行)的數量。我有33個這些範圍,並使用非常緩慢的循環讓我的答案,沒問題。由於速度引起了人們的廣泛關注,我希望有任何幫助可以讓它更快運行。我可以擺脫for循環和「矢量化」或任何類型的「應用」解決方案嗎?子集化數據幀R避免循環

在此先感謝

代碼:

N.data<-c(1:33) 
Lower<-c(0,100000,125000,150000,175000,200000,225000,250000,275000,300000,325000,350000,375000,400000,425000,450000,475000,500000,550000,600000,650000,700000,750000,800000,850000,900000,950000,1000000,1100000,1200000,1300000,1400000,1500000) 

Upper<-c(100000,125000,150000,175000,200000,225000,250000,275000,300000,325000,350000,375000,400000,425000,450000,475000,500000,550000,600000,650000,700000,750000,800000,850000,900000,950000,1000000,1100000,1200000,1300000,1400000,1500000, 5000000) 

for (i in 1:(length(N.data))){ 
N.data[i]<-nrow(dataset[dataset$Z==c & dataset$X > Lower[i] & dataset$X < Upper[i],]) 
} 
+0

你可以發佈你的數據幀的至少一個子集(那個有100萬行的?) – TARehman 2013-03-05 14:30:09

+0

'N.data <-c(1:33)'。 '長度(N.data)'。 '[1] 33' – vaettchen 2013-03-05 14:36:00

回答

0

apply功能不被量化。它們只是for循環的更高效的實現。爲了達到你使用矢量化的目的,這裏有一種方法。

# Create a Dummy Dataset and Breaks 
dataset = data.frame(
    X = rpois(100, 10), 
    Z = rpois(100, 20) 
) 
breaks = seq(0, max(dataset$Z), length = 5) 

# Add Column with Breaks 
dataset = transform(dataset, Z2 = cut(Z, breaks, labels = FALSE)) 


# Use Aggregate to compute length for each value of Z2 
c = 10 
aggregate(Z ~ Z2, data = dataset, length, subset = (X == c)) 

這應該是更有效的,使用mapply,因爲它是完全矢量化。

+0

非常感謝您的回覆。我當然可以看到這是一個更有效的實現。鑑於上述建議爲「空」範圍提供零值,您只需省略。我怎樣才能改變你的最後一行代碼返回0爲空範圍。在此先感謝 – Smackboyg 2013-03-05 18:11:37

+0

這裏不需要回答,我自己使用簡單的ifelse語句找到了解決方案。 – Smackboyg 2013-03-05 18:57:56

1

更有效的方法:

# first logical index (vector) 
idx1 <- dataset$Z == c 

# second logical index (matrix) 
idx2 <- mapply(function(l, u) dataset$X > l & dataset$X < u, Lower, Upper) 

# combine both indices and count number of rows 
N.data <- colSums(idx1 & idx2) 
+0

輝煌,非常感謝! – Smackboyg 2013-03-05 14:46:39