2012-01-20 35 views
13

我想創建一個數據框的子集,當我這樣做時,R切換日期列的格式。任何想法爲什麼或如何解決這個問題?cbind()正在改變日期格式

> head(spyPr2) 
     Date Open High Low Close Volume Adj.Close 
1 12/30/2011 126.02 126.33 125.50 125.50 95599000 125.50 
2 12/29/2011 125.24 126.25 124.86 126.12 123507200 126.12 
3 12/28/2011 126.51 126.53 124.73 124.83 119107100 124.83 
4 12/27/2011 126.17 126.82 126.06 126.49 86075700 126.49 
5 12/23/2011 125.67 126.43 125.41 126.39 92187200 126.39 
6 12/22/2011 124.63 125.40 124.23 125.27 119465400 125.27 
> spyPr2$Date <- as.Date(spyPr2$Date, format = "%m/%d/%Y") 
> head(spyPr2) 
     Date Open High Low Close Volume Adj.Close 
1 2011-12-30 126.02 126.33 125.50 125.50 95599000 125.50 
2 2011-12-29 125.24 126.25 124.86 126.12 123507200 126.12 
3 2011-12-28 126.51 126.53 124.73 124.83 119107100 124.83 
4 2011-12-27 126.17 126.82 126.06 126.49 86075700 126.49 
5 2011-12-23 125.67 126.43 125.41 126.39 92187200 126.39 
6 2011-12-22 124.63 125.40 124.23 125.27 119465400 125.27 
> spyPr2 <- data.frame(cbind(spyPr2$Date, spyPr2$Close, spyPr2$Adj.Close)) 
> str(spyPr2) 
'data.frame': 1638 obs. of 3 variables: 
$ X1: num 15338 15337 15336 15335 15331 ... 
$ X2: num 126 126 125 126 126 ... 
$ X3: num 126 126 125 126 126 ... 
> head(spyPr2) 
    X1  X2  X3 
1 15338 125.50 125.50 
2 15337 126.12 126.12 
3 15336 124.83 124.83 
4 15335 126.49 126.49 
5 15331 126.39 126.39 
6 15330 125.27 125.27 

UPDATE:

> spyPr2 <- data.frame(cbind(spyPr2["Date"], spyPr2$Close, spyPr2$Adj.Close)) 
Error in `[.data.frame`(spyPr2, "Date") : undefined columns selected 
> spyPr2 <- data.frame(cbind(spyPr2[,"Date"], spyPr2$Close, spyPr2$Adj.Close)) 
Error in `[.data.frame`(spyPr2, , "Date") : undefined columns selected 

更新2:

structure(list(Date = structure(c(15338, 15337, 15336, 15335, 
15331, 15330), class = "Date"), Open = c(126.02, 125.24, 126.51, 
126.17, 125.67, 124.63), High = c(126.33, 126.25, 126.53, 126.82, 
126.43, 125.4), Low = c(125.5, 124.86, 124.73, 126.06, 125.41, 
124.23), Close = c(125.5, 126.12, 124.83, 126.49, 126.39, 125.27 
), Volume = c(95599000L, 123507200L, 119107100L, 86075700L, 92187200L, 
119465400L), Adj.Close = c(125.5, 126.12, 124.83, 126.49, 126.39, 
125.27)), .Names = c("Date", "Open", "High", "Low", "Close", 
"Volume", "Adj.Close"), row.names = c(NA, -6L), class = "data.frame") 
+0

您是否嘗試過使用'['而不是'$'選擇?例如'spyPr2 [「Date」]' – James

+0

向我們展示'dput(head(spyPr2))'的結果',所以我們不必費力創建自己的數據來查看發生了什麼。我懷疑默認的'cbind()'方法是這裏的問題,但是想在我自己的機器上運行代碼來檢查。 –

+0

不,對不起,我的意思是在你處理它之前來自'dput()'*的輸出。即Give是你的輸入數據(但是我們只需要你顯示的6行) –

回答

41

答案顯然是不做子集一樣,!使用適當的工具。有什麼問題

spyPr2.new <- spyPr2[, c("Date", "Close", "Adj.Close")] 

要解釋您所看到的行爲,您需要了解$返回的內容以及cbind()的工作方式。 cbind()是R中的那些古怪其中方法分派不經由通常的方法進行,但通過埋在R.這的內部特殊代碼代替處理是所有的R代碼後面cbind()之一:

> cbind 
function (..., deparse.level = 1) 
.Internal(cbind(deparse.level, ...)) 
<bytecode: 0x24fa0c0> 
<environment: namespace:base> 

不多幫忙,呃?有數據幀的方法和但是"ts"對象:

> methods(cbind) 
[1] cbind.data.frame cbind.ts*  

    Non-visible functions are asterisked 

之前,我做了揭示,還要注意什麼$回報(dat2是你的6行數據轉換Date"Date"對象後):

> str(dat2$Date) 
Date[1:6], format: "2011-12-30" "2011-12-29" "2011-12-28" "2011-12-27" ... 

這是一個"Date"對象,它確實是一個特殊的矢量。

> class(dat2$Date) 
[1] "Date" 

關鍵的一點是,它是不是一個數據幀。因此,當您使用cbind()時,內部代碼會看到三個向量,內部代碼會創建一個矩陣。

> (c1 <- cbind(dat2$Date, dat2$Close, dat2$Adj.Close)) 
     [,1] [,2] [,3] 
[1,] 15338 125.50 125.50 
[2,] 15337 126.12 126.12 
[3,] 15336 124.83 124.83 
[4,] 15335 126.49 126.49 
[5,] 15331 126.39 126.39 
[6,] 15330 125.27 125.27 
> class(c1) 
[1] "matrix" 

只能有R中的數字或字符的矩陣所以Date對象被轉換爲數字向量:

> as.numeric(dat2$Date) 
[1] 15338 15337 15336 15335 15331 15330 

以允許cbind()以產生數字矩陣。

你可以通過調用它明確地強制使用數據幀的方法,它不知道如何處理"Date"對象,因此不會做任何的轉換:

> cbind.data.frame(dat2$Date, dat2$Close, dat2$Adj.Close) 
    dat2$Date dat2$Close dat2$Adj.Close 
1 2011-12-30  125.50   125.50 
2 2011-12-29  126.12   126.12 
3 2011-12-28  124.83   124.83 
4 2011-12-27  126.49   126.49 
5 2011-12-23  126.39   126.39 
6 2011-12-22  125.27   125.27 

然而,所有的解釋之外,您正嘗試以非常複雜的方式進行子集設置。[作爲一個子集函數工作得很好:

> dat2[, c("Date", "Close", "Adj.Close")] 
     Date Close Adj.Close 
1 2011-12-30 125.50 125.50 
2 2011-12-29 126.12 126.12 
3 2011-12-28 124.83 124.83 
4 2011-12-27 126.49 126.49 
5 2011-12-23 126.39 126.39 
6 2011-12-22 125.27 125.27 

subset()也是一種選擇,但這裏並不需要:

> subset(dat2, select = c("Date", "Close", "Adj.Close")) 
     Date Close Adj.Close 
1 2011-12-30 125.50 125.50 
2 2011-12-29 126.12 126.12 
3 2011-12-28 124.83 124.83 
4 2011-12-27 126.49 126.49 
5 2011-12-23 126.39 126.39 
6 2011-12-22 125.27 125.27 
+0

這樣做,非常感謝,甚至沒有想過這樣做 – screechOwl

+3

cbind.data.frame有助於合併其他日期列上下文以及 – etov

+0

太棒了!感謝您提供'cbind.data.frame'方法。我必須對來自不同表的列執行cbind操作,因此無法使用子集方法。 –

4

我想我可能把這稱爲drop = FALSE疑難雜症的數據幀的一個隱藏的實例。

當您使用cbind時,如果至少有一個組件也是數據框,則它僅使用數據框方法。否則,爲了構建矩陣,所有內容都被轉換爲單一類型。

因此,像spyPr2$DatespyPr2[,'Date']元件主叫cbind將導致基質(失去的時間結構),這將不通過纏繞這一切在data.frame神奇地恢復。

如果您使用[來選擇每一列,但只能使用drop = FALSE,這會阻止R將結果轉換爲向量(這會使您將R右轉回到開始時將R強制爲矩陣) :

​​

就足夠了,因爲您只需要其中一個組件成爲數據框。

但是Gavin一般來說是正確的,你不應該以這種方式對數據框進行子集化。