2013-03-05 87 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