3

我有一个我称之为“d”的数据框,格式如下:

        Date   Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct   Nov  Dec
        1 1895 12.63 2.47 2.69 2.43 3.10 1.65 0.13 0.24 1.78 0.18  3.32 7.78
        2 1896 13.08 3.86 5.14 5.91 1.61 0.10 0.00 0.05 0.44 3.76  9.51 8.71
        3 1897  4.10 7.16 6.38 0.85 0.47 0.87 0.00 0.00 0.46 2.51  5.27 3.40
        4 1898  1.97 6.14 0.29 0.30 2.40 0.49 0.00 0.00 1.10 1.32  2.40 2.11
        5 1899  7.61 2.69 8.12 1.56 1.66 0.75 0.00 0.18 0.31 7.87 10.79 5.20
        6 1900  8.68 2.44 3.53 1.75 2.95 0.33 0.00 0.25 0.60 5.69  9.38 5.00

我想改写成如下形式

        Date               Precip
        1 1895-01-01       12.63 
        2 1895-02-01        2.47 
        3 1895-03-01        2.69 
        4 1895-04-01        2.43

         ...

        70 1900-10-01       5.69
        71 1900-11-01       9.38 
        72 1900-12-01       5.00

我能想到的唯一方法是创建一个新的数据框,其中包含从开始到结束的日期序列,然后使用 rbind 将数据框“d”的行连接到新的数据框。在不使用 for 循环的情况下,有没有更简洁的方法?感谢您的帮助!

4

5 回答 5

7

我使用stackas.Date

dat.l <- data.frame(dat[,1],stack(dat[,-1]))
dat <- data.frame(Date =as.Date(paste(dat.l[,1],dat.l[,3],'01',sep='/'),format='%Y/%b/%d'),
           Precip= dat.l[,2])

          Date Precip
1  1895-01-01  12.63
2  1896-01-01  13.08
3  1897-01-01   4.10
.....

70 1898-12-01   2.11
71 1899-12-01   5.20
72 1900-12-01   5.00

我注意到我的数据没有按照我在每个日期订购的顺序排列:

  dat[order(dat$Date),]
             Date Precip
    1  1895-01-01  12.63
    7  1895-02-01   2.47
    13 1895-03-01   2.69
    19 1895-04-01   2.43
    25 1895-05-01   3.10
    31 1895-06-01   1.65
于 2013-03-02T00:13:59.147 回答
4

我没有从您建议的日期策略开始的 for 循环就做到了。

df2 <- data.frame(Date = seq.Date(as.Date("1895-01-01"), 
                                   as.Date("1900-12-01"),
                                   by="month"),
                   Precip =c(t(data.matrix(dfrm[-1]) ) ))
head(df2)
        Date Precip
1 1895-01-01  12.63
2 1895-02-01   2.47
3 1895-03-01   2.69
4 1895-04-01   2.43
5 1895-05-01   3.10
6 1895-06-01   1.65
于 2013-03-02T00:07:50.600 回答
2

您可能想在这里处理时间序列对象:

    x <- c(12.63, 2.47, 2.69, 2.43, 3.1, 1.65, 0.13, 0.24, 1.78, 0.18, 
3.32, 7.78, 13.08, 3.86, 5.14, 5.91, 1.61, 0.1, 0, 0.05, 0.44, 
3.76, 9.51, 8.71, 4.1, 7.16, 6.38, 0.85, 0.47, 0.87, 0, 0, 0.46, 
2.51, 5.27, 3.4, 1.97, 6.14, 0.29, 0.3, 2.4, 0.49, 0, 0, 1.1, 
1.32, 2.4, 2.11, 7.61, 2.69, 8.12, 1.56, 1.66, 0.75, 0, 0.18, 
0.31, 7.87, 10.79, 5.2, 8.68, 2.44, 3.53, 1.75, 2.95, 0.33, 0, 
0.25, 0.6, 5.69, 9.38, 5)
x.ts <- ts(x, frequency=12, start=(1895))

x.ts
##        Jan   Feb   Mar   Apr   May   Jun   Jul   Aug   Sep   Oct   Nov   Dec
## 1895 12.63  2.47  2.69  2.43  3.10  1.65  0.13  0.24  1.78  0.18  3.32  7.78
## 1896 13.08  3.86  5.14  5.91  1.61  0.10  0.00  0.05  0.44  3.76  9.51  8.71
## 1897  4.10  7.16  6.38  0.85  0.47  0.87  0.00  0.00  0.46  2.51  5.27  3.40
## 1898  1.97  6.14  0.29  0.30  2.40  0.49  0.00  0.00  1.10  1.32  2.40  2.11
## 1899  7.61  2.69  8.12  1.56  1.66  0.75  0.00  0.18  0.31  7.87 10.79  5.20
## 1900  8.68  2.44  3.53  1.75  2.95  0.33  0.00  0.25  0.60  5.69  9.38  5.00

然后xts将其格式化为您想要的格式(以及可以使用时间序列完成的其他事情):

head(as.xts(x.ts))
##           [,1]
## Jan 1895 12.63
## Feb 1895  2.47
## Mar 1895  2.69
## Apr 1895  2.43
## May 1895  3.10
## Jun 1895  1.65
于 2013-03-02T00:29:30.127 回答
2

使用的解决方案data.table

require(data.table)
dt <- data.table(dat, key="Date")
dt.out <- dt[, list(Date_01 = as.Date(paste(Date, 1:12, "01", sep="/")), 
        Precip = unlist(.SD)), by=Date][, Date := NULL]
setnames(dt.out, "Date_01", "Date")
于 2013-03-02T00:35:21.713 回答
1

是的,查看包melt中的功能reshape2。这实际上非常简单。在这里阅读更多:http: //www.jstatsoft.org/v21/i12/paper

你会这样做:

install.packages("reshape2")
library(reshape2)
melt(DF, id="Date", measured=c(2:13))
于 2013-03-02T00:06:45.260 回答