2016-04-16 39 views
0
一個較大的數據幀

我正在尋找一種有效的方式把這樣的數據幀:試圖增加的功能效率,其將一個數據幀劃分成,使用R

1 45 
2 49 
5 25 
6 24 
9 32 
11 39 

成這樣一個數據幀:

1 45 
2 49 
3 49 
4 49 
5 25 
6 24 
7 24 
8 24 
9 32 
10 32 
11 39 

因此,這基本上是在行中添加左列中序列中的缺失值並使用右列中的最後一個值。我試圖爲1,000,000行的數據框做到這一點,我的功能非常慢。我認爲必須有一個更快的方法。

我做的是首先把它變成一個data.frame我打電話w方式:

1 45 
2 49 
3 0 
4 0 
5 25 
6 24 
7 0 
8 0 
9 32 
10 0 
11 39 

這一步是相當快的,而不是一個問題,但後來我用:

for (i in 1:nrow(w)) { 
    if(w[i,2]==0) {w[i,2]<-w[i-1,2]} 
} 

大部分時間都花在'< - '上,但我嘗試了很多不同的方式,這是我能想到的最快速度。當我做20,000行時很快,但當我嘗試1,000,000行時,大約需要30分鐘。

有沒有人有任何想法?

+0

快速qn:第1列的最大值是多少? – chinsoon12

+0

最大值將根據我正在使用的數據集而變化。 – AndrewK

回答

2

使用每個值之間的diff erences在第一列rep吃的每一行:

out <- dat[rep(rownames(dat), c(diff(dat$V1), 1)),] 
out$V1 <- seq_len(nrow(out)) 
out 

# V1 V2 
#1 1 45 
#2 2 49 
#2.1 3 49 
#2.2 4 49 
#3 5 25 
#4 6 24 
#4.1 7 24 
#4.2 8 24 
#5 9 32 
#5.1 10 32 
#6 11 39 

其中dat是:

dat <- structure(list(V1 = c(1L, 2L, 5L, 6L, 9L, 11L), V2 = c(45L, 49L, 
25L, 24L, 32L, 39L)), .Names = c("V1", "V2"), class = "data.frame", 
row.names = c(NA,-6L)) 
+0

對於第一列,您可能只需要'rep(df $ V2,c(diff(df $ V1),1))'而不使用子表達式。 –

+0

謝謝。我會比較回家時的速度。 – AndrewK

+0

太棒了。現在不到1秒,而我的舊功能只需30分鐘! – AndrewK

0

這裏是expand.gridna.locf

另一種選擇
library(dplyr) 
library(zoo) 
expand.grid(V1= min(dat$V1):max(dat$V1)) %>% 
       left_join(., dat) %>% 
       mutate(V2= na.locf(V2)) 
# V1 V2 
#1 1 45 
#2 2 49 
#3 3 49 
#4 4 49 
#5 5 25 
#6 6 24 
#7 7 24 
#8 8 24 
#9 9 32 
#10 10 32 
#11 11 39 
0

這是另一種使用tidyr包的解決方案:

library(tidyr) 
dat %>% 
    complete(V1 = full_seq(V1, 1)) %>% 
    fill(V2)