【问题标题】:Any way to reconstruct new data.frame by merging multiple data.frame in R?有什么方法可以通过在 R 中合并多个 data.frame 来重建新的 data.frame?
【发布时间】:2018-04-04 17:39:11
【问题描述】:

我有多个data.frame,每个都有相同的气象站坐标​​,但包含不同年份的温度观测。但是,我打算构建新的data.frame,其中站的坐标将保持不变,但将从原始的多个data.frame 以编程方式添加相应的年度温度列。也许使用dplyr 包可能会有所帮助,但我有一些问题要连接YearAnnual_Temp 列并以编程方式构造新列。因为我有 35 个 data.frame,每个都有相同的 IDlonglat,但 Annual_Temp 各不相同。我需要通过合并 data.frame 来构造干净的表格数据。我怎样才能在 R 中实现这一点?有什么方法可以使用dplyr 来完成这项工作?有什么想法吗?

例如,这里是前三个data.frame的头部:

> multiple_DF

$air_temp.1980
      Year         ID long   lat Annual_Temp
34090 1980 6.25_51.75 6.25 51.75   10.709091
34091 1980 6.25_51.25 6.25 51.25   10.581818
34092 1980 6.25_50.75 6.25 50.75    9.500000
34224 1980 6.75_51.75 6.75 51.75   10.354545
34225 1980 6.75_51.25 6.75 51.25   10.636364
34226 1980 6.75_50.75 6.75 50.75    9.872727

$air_temp.1981
       Year         ID long   lat Annual_Temp
119884 1981 6.25_51.75 6.25 51.75   10.727273
119885 1981 6.25_51.25 6.25 51.25   10.563636
119886 1981 6.25_50.75 6.25 50.75    9.654545
120018 1981 6.75_51.75 6.75 51.75   10.409091
120019 1981 6.75_51.25 6.75 51.25   10.654545
120020 1981 6.75_50.75 6.75 50.75    9.954545

$air_temp.1982
       Year         ID long   lat Annual_Temp
205678 1982 6.25_51.75 6.25 51.75    11.80909
205679 1982 6.25_51.25 6.25 51.25    11.58182
205680 1982 6.25_50.75 6.25 50.75    10.61818
205812 1982 6.75_51.75 6.75 51.75    11.44545
205813 1982 6.75_51.25 6.75 51.25    11.73636
205814 1982 6.75_50.75 6.75 50.75    10.85455

所需的输出(更新)

我想生成新的data.frame,其中Annual_Temp 将被添加为Annual_TempYear 必须连接的新列。这是我想要的所需 data.frame:

      ID long   lat Ann_temp_1980 Ann_temp_1981 Ann_temp_1982
1 6.25_51.75 6.25 51.75     10.709091     10.727273        11.80909
2 6.25_51.25 6.25 51.25     10.581818     10.563636        11.58182
3 6.25_50.75 6.25 50.75      9.500000      9.654545        10.61818
4 6.75_51.75 6.75 51.75     10.354545     10.409091        11.44545
5 6.75_51.25 6.75 51.25     10.636364     10.654545        11.73636
6 6.75_50.75 6.75 50.75      9.872727      9.954545        10.85455

如何在 R 中以编程方式实现这一点?任何的想法?

重现示例数据:

multiple_DF = structure(list(air_temp.1980 = structure(list(Year = c(1980L, 
1980L, 1980L, 1980L, 1980L, 1980L), ID = c("6.25_51.75", "6.25_51.25", 
"6.25_50.75", "6.75_51.75", "6.75_51.25", "6.75_50.75"), long = c(6.25, 
6.25, 6.25, 6.75, 6.75, 6.75), lat = c(51.75, 51.25, 50.75, 51.75, 
51.25, 50.75), Annual_Temp = c(10.709091, 10.581818, 9.5, 10.354545, 
10.636364, 9.872727)), .Names = c("Year", "ID", "long", "lat", 
"Annual_Temp"), row.names = c(NA, -6L), class = "data.frame"), 
    air_temp.1981 = structure(list(Year = c(1981L, 1981L, 1981L, 
    1981L, 1981L, 1981L), ID = c("6.25_51.75", "6.25_51.25", 
    "6.25_50.75", "6.75_51.75", "6.75_51.25", "6.75_50.75"), 
        long = c(6.25, 6.25, 6.25, 6.75, 6.75, 6.75), lat = c(51.75, 
        51.25, 50.75, 51.75, 51.25, 50.75), Annual_Temp = c(10.727273, 
        10.563636, 9.654545, 10.409091, 10.654545, 9.954545)), .Names = c("Year", 
    "ID", "long", "lat", "Annual_Temp"), row.names = c(NA, -6L
    ), class = "data.frame"), air_temp.1982 = structure(list(
        Year = c(1982L, 1982L, 1982L, 1982L, 1982L, 1982L), ID = c("6.25_51.75", 
        "6.25_51.25", "6.25_50.75", "6.75_51.75", "6.75_51.25", 
        "6.75_50.75"), long = c(6.25, 6.25, 6.25, 6.75, 6.75, 
        6.75), lat = c(51.75, 51.25, 50.75, 51.75, 51.25, 50.75
        ), Annual_Temp = c(11.80909, 11.58182, 10.61818, 11.44545, 
        11.73636, 10.85455)), .Names = c("Year", "ID", "long", 
    "lat", "Annual_Temp"), row.names = c(NA, -6L), class = "data.frame")), .Names = c("air_temp.1980", 
"air_temp.1981", "air_temp.1982"))

【问题讨论】:

  • Fwiw,我认为您应该制作两张表:一张具有时间不变的 ID 属性(lat、long);另一个带有年份变化的变量,带有 cols ID、Year、Annual_Temp。推理由 dplyr 包的作者在本文中介绍:jstatsoft.org/article/view/v059i10
  • @Frank 能否为这个问题提供方便的解决方案?
  • 是的,我想是的。你能让这个问题(更容易)重现吗?这看起来类似于您可以从一些内置数据集开始(尝试data());您可能还希望看到此问答正在制作一个可重复的示例:stackoverflow.com/questions/5963269/…(我会接受一些;很快就无法发布答案了。)
  • @Frank 也许使用dput 可以成为一个可重复的例子。你能分享你的想法吗?谢谢
  • Jerry,这是一个用于生成可重现示例的好工具。在你的每一帧上使用它,也许是dput(head(x,n=10)),然后发布输出(每个帧都应该以structure(...开头)。但是,head 是不够的:您需要在所有帧中拥有足够的数据,以便正确完成合并,并且此示例数据中有足够的可变性以查看合并中的差异。因此,您可能需要从每一帧中选择非常具体的行。 (有 6 到 12 行是一个不错的选择,但总是会有所不同。)

标签: r dataframe dplyr


【解决方案1】:

首先,将表格合并为长格式:

library(data.table)
L = lapply(multiple_DF, data.table)

bigDT = rbindlist(L, id="src")

              src Year         ID long   lat Annual_Temp
 1: air_temp.1980 1980 6.25_51.75 6.25 51.75   10.709091
 2: air_temp.1980 1980 6.25_51.25 6.25 51.25   10.581818
 3: air_temp.1980 1980 6.25_50.75 6.25 50.75    9.500000
 4: air_temp.1980 1980 6.75_51.75 6.75 51.75   10.354545
 5: air_temp.1980 1980 6.75_51.25 6.75 51.25   10.636364
 6: air_temp.1980 1980 6.75_50.75 6.75 50.75    9.872727
 7: air_temp.1981 1981 6.25_51.75 6.25 51.75   10.727273
 8: air_temp.1981 1981 6.25_51.25 6.25 51.25   10.563636
 9: air_temp.1981 1981 6.25_50.75 6.25 50.75    9.654545
10: air_temp.1981 1981 6.75_51.75 6.75 51.75   10.409091
11: air_temp.1981 1981 6.75_51.25 6.75 51.25   10.654545
12: air_temp.1981 1981 6.75_50.75 6.75 50.75    9.954545
13: air_temp.1982 1982 6.25_51.75 6.25 51.75   11.809090
14: air_temp.1982 1982 6.25_51.25 6.25 51.25   11.581820
15: air_temp.1982 1982 6.25_50.75 6.25 50.75   10.618180
16: air_temp.1982 1982 6.75_51.75 6.75 51.75   11.445450
17: air_temp.1982 1982 6.75_51.25 6.75 51.25   11.736360
18: air_temp.1982 1982 6.75_50.75 6.75 50.75   10.854550

然后在某种程度上将数据“规范化”到多个表中:

ID_attr = unique(bigDT[, c("ID", "lat", "long")])

           ID   lat long
1: 6.25_51.75 51.75 6.25
2: 6.25_51.25 51.25 6.25
3: 6.25_50.75 50.75 6.25
4: 6.75_51.75 51.75 6.75
5: 6.75_51.25 51.25 6.75
6: 6.75_50.75 50.75 6.75

meas_data = bigDT[, c("Year", "ID", "Annual_Temp")]

    Year         ID Annual_Temp
 1: 1980 6.25_51.75   10.709091
 2: 1980 6.25_51.25   10.581818
 3: 1980 6.25_50.75    9.500000
 4: 1980 6.75_51.75   10.354545
 5: 1980 6.75_51.25   10.636364
 6: 1980 6.75_50.75    9.872727
 7: 1981 6.25_51.75   10.727273
 8: 1981 6.25_51.25   10.563636
 9: 1981 6.25_50.75    9.654545
10: 1981 6.75_51.75   10.409091
11: 1981 6.75_51.25   10.654545
12: 1981 6.75_50.75    9.954545
13: 1982 6.25_51.75   11.809090
14: 1982 6.25_51.25   11.581820
15: 1982 6.25_50.75   10.618180
16: 1982 6.75_51.75   11.445450
17: 1982 6.75_51.25   11.736360
18: 1982 6.75_50.75   10.854550

我认为这种格式比 OP 请求的宽格式(年份嵌入在字符串列名中)更容易使用。 Hadley Wickham 的tidy data paper 可能是一个有用的参考。

要在 dplyr 中执行此操作,请使用 bind_rows 而不是 rbindlist;或者只是 do.call(rbind, L) 在基础 R 中。

【讨论】:

    【解决方案2】:

    正如弗兰克指出的那样,使用可重复的数据会更容易,但我认为以下方法会起作用:

    library(tidyverse)
    DF<-do.call("rbind", multiple_DF)
    DF$Year<-paste0("Ann_temp_",DF$Year)
    DF_final<-spread(DF,Year,Annual_Temp)
    

    【讨论】:

      猜你喜欢
      • 2013-01-24
      • 2016-02-22
      • 1970-01-01
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 2022-11-18
      相关资源
      最近更新 更多