2013-07-23 66 views
2

我有一個只有一列和158112不同值的數據幀。值不是隨機排列的。每24個值代表一天。每天在那裏列出18次,接下來是第二天,例如。 01.01.2012爲18x24,02.01.2012爲18x24等等。重組數據幀

 df 
1  593 
2  939 
3  734 
4  791 
5  184 
6  495 
... 
158112 683 

我想組織他們在一個新的數據幀不同的結構。該過程將如下所示:

取前24個值並將它們放入新數據框「new_df」列號。 1,取下24個值,並放入「new_df」列號。 2,拿下24個值放入「new_df」列號。 3.這樣做直到18列填充每個24值,然後再從第1列開始,並添加接下來的24個值,等等......所以最後我想擁有18列的「new_df」每個8784行。

任何想法?

回答

1

我想你想要像下面這樣:

# sample data 
mydf <- data.frame(df=rnorm(18*8784,0,1)) 
# split dataframe into chunks (of 18*24) 
mylist <- split(mydf,rep(1:366,each=432)) 
# turn each chunk into a matrix of the right shape and `rbind` them back together 
new_df <- do.call(rbind, lapply(mylist, function(x) matrix(x[,1],nrow=24))) 

您可以檢查,如果這是正確的有:

all.equal(mydf[1:24,1],new_df[1:24,1]) # first 24 values are first column 
all.equal(mydf[25:48,1],new_df[1:24,2]) # next 24 values are second column 
all.equal(mydf[433:456,1],new_df[25:48,1]) # day 2 starts in the first column 

所有這些都應該是TRUE。我想你想要它作爲data.frame,所以只需使用as.data.frame(new_df)即可將結果返回到data.frame中。

+0

+1爲了OP要求的準確性;然而,你也應該看看'數組'來處理分裂,就像我在[這裏](http://stackoverflow.com/a/17816070/1270695)。 – A5C1D2H2I1M1N2O1R2T1

+0

謝謝。我剛剛開始熟悉'array',你的解決方案看起來很光滑。它也更有效率嗎? – Thomas

+0

如果OP在我的答案中創建'array'階段時停下來,它*應該*相當快。 R在矩陣上的運行速度比在data.frame上快,所以我認爲這同樣適用於數組。在最後一步中,我將(* again *)轉換爲「xts」,結果得到的「xts」對象將數據存儲爲「矩陣」,這比「data.frame」更有效。 – A5C1D2H2I1M1N2O1R2T1

2

試試這個:

set.seed(1) 
df <- data.frame(df=sample(1:999, 158112, TRUE)) # creating some data 
new_df <- data.frame(matrix(unlist(df), ncol=18)) # putting df into a 8784 x 18 data.frame 
dim(new_df) # checking the dimensions of new_df 
+0

我同意(並進行類似考慮df < - data.frame(x = seq(158112)); new_df < - do.call(rbind,tapply(df [,1],rep(seq(366),each = 18 * 24) ,ncol = 18))')... – texb

+0

那不完全是我想要的。原始數據框不是隨機排列的。它代表2012年每小時的每一天,但每天18次,每次都有不同的值。 –

+0

@Henning_FL這個信息應該在你的問題中,使其更清晰,否則我假設一些背景以提供答案。請記住,答案的質量與問題的質量密切相關。 –

1

也許比迄今爲止的替代方案更好使用array來操縱你的數據到你想要的結構。由於您只是處理單個矢量,並且想要按列填充數據,因此只需將dim分配給您的矢量。

這裏是一個簡化的例子。我們將與長度40

mydata <- rep(1:8, each = 5) 
mydata 
# [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 
# [21] 5 5 5 5 5 6 6 6 6 6 7 7 7 7 7 8 8 8 8 8 

的矢量開始現在,假設我們想在第一個20個值被組合在一起,並在第二次20個值組合在一起,這種轉換成四列。 (在你的數據,這將是組合在一起的第一個24點* 18的值來表示的記錄18列一天。)

下面是我們該怎麼做:

myarray <- array(mydata, dim=c(5, 4, 2), 
       dimnames = list(NULL, NULL, 
           c("2012-01-01", "2012-01-02"))) 
myarray 
# , , 2012-01-01 
# 
#  [,1] [,2] [,3] [,4] 
# [1,] 1 2 3 4 
# [2,] 1 2 3 4 
# [3,] 1 2 3 4 
# [4,] 1 2 3 4 
# [5,] 1 2 3 4 
# 
# , , 2012-01-02 
# 
#  [,1] [,2] [,3] [,4] 
# [1,] 5 6 7 8 
# [2,] 5 6 7 8 
# [3,] 5 6 7 8 
# [4,] 5 6 7 8 
# [5,] 5 6 7 8 

也許你想停止在此刻。但是,如果您想一路走到一個data.frame,那也很容易。

使用@ Jilber的樣本數據只是爲了便於複製的目的:

set.seed(1) 
df <- data.frame(df=sample(1:999, 158112, TRUE)) 
# Hopefully you've done your math correctly 
# R will recycle if the dims aren't correct 
# for your data. 
Ndays <- nrow(df)/(24*18) 
dfarray <- array(df$df, 
       dim = c(24, 18, Ndays), 
       # Add dimnames by creating a date sequence 
       dimnames = list(NULL, NULL, as.character(
        seq(as.Date("2012-01-01"), by = "1 day", 
         length.out = Ndays)))) 
# Use `apply` to convert this to a `list` of `data.frame`s 
temp <- apply(dfarray, 3, as.data.frame) 
# Use `lapply` to create your intermediate `data.frame`s 
out <- lapply(names(temp), function(x) { 
    data.frame(date = as.Date(x), temp[[x]]) 
}) 
# Use `do.call(rbind, ...)` to get your final `data.frame` 
final <- do.call(rbind, out) 

第一輸出看起來像這樣的幾行:

head(final) 
#   date V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 
# 1 2012-01-01 266 267 732 347 455 991 729 724 101 649 307 702 133 841 443 
# 2 2012-01-01 372 386 693 334 410 496 453 338 927 953 578 165 222 720 157 
# 3 2012-01-01 573 14 478 476 811 484 175 630 283 953 910 65 227 267 582 
# 4 2012-01-01 908 383 861 892 605 174 746 840 590 340 143 754 132 495 970 
# 5 2012-01-01 202 869 438 864 655 755 105 856 111 263 415 620 981 84 989 
# 6 2012-01-01 898 341 245 390 353 454 864 391 840 166 211 170 327 354 177 
# V16 V17 V18 
# 1 109 232 12 
# 2 333 241 940 
# 3 837 797 993 
# 4 277 831 358 
# 5 587 114 747 
# 6 836 963 793 

我還是做強烈建議您熟悉「xts」包,但如果您要使用時間序列數據做很多工作。從

轉換「最終」 data.frame以上的xts目標很簡單:

library(xts) 
Final <- xts(final[-1], order.by=final[[1]]) 

,這將讓你輕鬆做有趣的事情是這樣的:

apply.quarterly(Final, mean) 
#     V1  V2  V3  V4  V5  V6 
# 2012-03-31 490.5256 493.8338 507.4272 503.5421 495.0929 494.4025 
# 2012-06-30 511.5792 508.1493 500.9043 500.2152 509.0614 499.9881 
# 2012-09-30 496.2672 501.1399 496.3542 493.7423 504.8170 507.1671 
# 2012-12-31 503.9583 502.5616 502.8936 509.2120 503.2387 502.4678 
#     V7  V8  V9  V10  V11  V12 
# 2012-03-31 490.2477 492.2115 510.6525 499.8168 506.9510 494.3654 
# 2012-06-30 494.0962 497.0357 506.9267 500.2198 501.4263 494.1117 
# 2012-09-30 509.9561 487.0543 497.2206 485.4511 498.1191 494.5190 
# 2012-12-31 503.0095 500.7903 494.7428 494.1409 502.0181 496.9764 
#     V13  V14  V15  V16  V17  V18 
# 2012-03-31 504.4130 499.8581 503.0023 501.0137 499.1021 504.7711 
# 2012-06-30 500.0504 501.2903 490.7582 502.7395 503.5737 496.4821 
# 2012-09-30 493.4860 499.2088 500.7260 503.1907 491.9583 490.4293 
# 2012-12-31 500.4348 507.9475 499.3637 486.4438 496.8220 492.8890