代码之家  ›  专栏  ›  技术社区  ›  fellowsk

创建包含多行的新列

  •  1
  • fellowsk  · 技术社区  · 10 年前

    我的数据框架如下:

    dat <- read.table(text=
    "ID | Year | Month | Variable | Value1 | Value2 | Value3
      1 | 1950 |   1   |   PRCP   |  0     |   1    |   0
      1 | 1950 |   1   |   TMAX   |  52    |   51   |   52
      1 | 1950 |   1   |   TMIN   |  41    |   41   |   39
      1 | 1950 |   2   |   PRCP   |  1     |   0    |   1
      1 | 1950 |   2   |   TMAX   |  55    |   57   |   58",
      header=TRUE, sep="|")
    

    有50个站点ID,年份跨度1950-2005年,1-12个月,有3个天气变量(PRCP、TMAX和TMIN),然后是一个月中每一天的Value1-Value31列,其中包含天气变量测量值。

    我想创建一个如下所示的数据帧:

    ID | Date       | PRCP
    1  | 1950-01-01 |  0
    1  | 1950-01-02 |  1
    1  | 1950-01-03 |  0
    

    到目前为止,我已经能够为每个天气变量创建3个单独的数据集,但我不知道如何创建新的列并相应地扩展行(每个月的每一天都需要31个新行)。我对R很陌生,如果有任何帮助,我会很感激的-谢谢!

    1 回复  |  直到 10 年前
        1
  •  0
  •   Community CDub    5 年前

    我们可以使用 melt/dcast 来自 data.table 。我们转换'数据。帧“到”数据。表'( setDT(dat) ),使用 melt ,创建按“ID”、“年”、“月”和“变量”分组的序列列(“ID”)。通过粘贴“年”、“月”和“ind”创建“日期”列,然后使用 dcast 。我们不需要创建三个单独的数据集,而是可以将所有信息存储在一个数据集中。

    library(data.table)#v1.9.6+
    dM <- melt(setDT(dat), measure=patterns('^Value'))
    dM1 <- dM[, ind:= 1:.N, by = .(ID, Year, Month, Variable)]
    dM1[, Date:=as.Date(sprintf('%04d-%02d-%02d', Year, Month, ind))]
    dcast(dM1, ID+Date~Variable, value.var='value1')
    #   ID       Date PRCP TMAX TMIN
    #1:  1 1950-01-01    0   52   41
    #2:  1 1950-01-02    1   51   41
    #3:  1 1950-01-03    0   52   39
    #4:  1 1950-02-01    1   55   NA
    #5:  1 1950-02-02    0   57   NA
    #6:  1 1950-02-03    1   58   NA
    

    注:在示例数据中,OP仅提供了3个值列。我猜在原始数据集中,它将是31列。

    数据

    dat <-  structure(list(ID = c(1, 1, 1, 1, 1), Year = c(1950, 1950, 1950, 
    1950, 1950), Month = c(1, 1, 1, 2, 2), Variable = c("PRCP", "TMAX", 
    "TMIN", "PRCP", "TMAX"), Value1 = c(0, 52, 41, 1, 55), Value2 = c(1, 
    51, 41, 0, 57), Value3 = c(0, 52, 39, 1, 58)), .Names = c("ID", 
    "Year", "Month", "Variable", "Value1", "Value2", "Value3"),
    row.names = c(NA, -5L), class = "data.frame")