0

我有以下问题:

为了分析天气对公民科学网页志愿者观察自然(动物、植物等)的影响,我需要将每日观察结果与最近气象站的天气信息相匹配。我正在使用rdwd(用于德国气象服务的数据)并且已经设法将每个观测位置与最近的气象站结合起来。所以我现在有一个这样的数据框(my_df_example),有 100 行:

     ID      Date         lat     long      Station_id                   Stationname
   1317186439 2019-05-03 47.77411 9.540569        4094     Weingarten, Kr. Ravensburg
   -2117439060 2019-05-19 48.87217 9.396229       10510             Winterbach/Remstal
   -630183789 2019-04-30 48.86810 9.285427        4928      Stuttgart (Schnarrenberg)
   -390672435 2019-05-10 50.71187 8.706279        1639             Giessen/Wettenberg
   262182713 2019-05-01 50.82548 8.892961        3164 Coelbe, Kr. Marburg-Biedenkopf
   -373270631 2019-05-24 51.61666 7.950153        5480                           Werl

使用输入(my_df_example):

   structure(list(ID = c(1317186439L, -2117439060L, -630183789L, -390672435L, 262182713L, -373270631L,...
   Datum = structure(c(1556841600, 1558224000, 1556582400, 1557446400, 1556668800, 1558656000, 1558224000, 1557532800,..., class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
   lat = c(47.7741093721703, 48.8721672952686, 48.8681024146134, 50.7118683229165, 50.8254843786222, 51.6166575725419, 48.7357007677785,...
   long = c(9.54056899481679, 9.3962287902832, 9.28542673587799, 8.70627880096436, 8.89296054840088, 7.95015335083008, 11.3105964660645,... 
   Stations_id = c(4094L, 10510L, 4928L, 1639L, 3164L, 5480L, 3484L,... 
   Stationsname = c("Weingarten, Kr. Ravensburg", "Winterbach/Remstal", "Stuttgart (Schnarrenberg)", "Giessen/Wettenberg", "Coelbe, Kr. Marburg-Biedenkopf", "Werl",... 
   row.names = c("58501", "89910", "69539", "24379", "45331", "77191", "50028", 
   class = "data.frame")

我现在需要做的是获取每个站点在该特定日期的天气信息。我正在尝试使用 R 中的 rdwd 包来执行此操作。到目前为止,我尝试了两种选择,但都没有成功。

选项1:

    urls <- selectDWD(name=my_df_final$Stationsname, res="daily", var="kl", per="historical", outvec=TRUE)
    kl <- dataDWD(urls[1:100])

这给了我一个包含 100 个列表的列表。100 个列表中的每个列表都包含某个站点记录的每一天的天气数据。所以我需要从这些列表中过滤数据,以便日期与 my_df_example 中的日期匹配。我不知道如何从列表中的列表中提取信息。

选项 2:

   stat <- my_df_example$Stationname
   link <- selectDWD(c(stat), res="daily", var="kl", per="hist") 
  file <- dataDWD(link, read=FALSE)
  clim <- readDWD(file, varnames=TRUE)

这里的问题是,dataDWD 不适用于列表。由于“链接”包含多个站名,因此它不仅仅是一个向量。

我真的不知道这些选项中的一个是否是正确的方式,或者替代方案是否更有意义。

感谢您提供的任何建议。

4

2 回答 2

0

根据你的问题:

我现在需要做的是获取每个站点在该特定日期的天气信息。

然后,一旦您有了列表列表 ( kl),您就可以从这个“元”列表中提取您正在以这种方式查找的信息:

query <- lapply(kl, function(x) {
  x[which((as.Date(x$MESS_DATUM) %in% as.Date(my_final_df$Date)) &
           (x$STATIONS_ID %in% my_final_df$Station_id)), ]
})

x表示kl传递给函数定义的对象。%in%正如其字母所示,该运算符将查找和变量之间共同元素,并且 (&) 还将查找和之间的匹配项。确保在对数据进行子集化时不会发生逻辑意外,并为两个数据框返回通用日期格式。$MESS_DATUM$DateSTATIONS_IDStation_idwhich()as.Date()

执行提取后,您必须将信息折叠到单个数据框中。由于 meta-list 内所有列表中的所有列都是相同的,所以可以直接使用do.call()+ rbind()。喜欢:

query <- do.call(rbind,query)

为避免混乱的行名,请调用:

rownames(query) <- NULL

然后,要查看查询数据集中的站名,请将查询与 my_final_df 合并:

colnames(query)[1] <- "Station_id" # the key needs to have the samen name in both data frames
query <- merge(query,my_final_df, by = "Station_id", all = TRUE)

最终结果如下所示:

   Station_id MESS_DATUM QN_3   FX  FM QN_4 RSK RSKF    SDK SHK_TAG  NM  VPM     PM  TMK   UPM  TXK TNK  TGK eor          ID       Date
2        1639 2019-05-01   10  7.1 2.0    3 0.0    0 11.383      NA 0.3  9.0 991.15 12.6 65.67 20.6 3.3 -0.4 eor  -390672435 2019-05-10
7        3164 2019-04-30   NA   NA  NA    3 0.0    0     NA       0  NA  8.9     NA 12.3 64.92 18.7 5.4  3.4 eor   262182713 2019-05-01
16       4094 2019-05-10   10 10.3 3.4    3 5.7    4  5.933      NA  NA 10.4     NA 11.9 76.04 16.8 8.5  6.8 eor  1317186439 2019-05-03
21       4928 2019-05-03   10 10.0 3.2    3 0.4    6  3.183      NA 7.5  9.0 973.66 10.4 72.38 14.2 7.8  7.3 eor  -630183789 2019-04-30
29       5480 2019-05-19   10 11.0 1.8    3 1.0    6  5.000      NA 7.2 13.0 995.10 14.0 82.38 21.8 6.8  5.2 eor  -373270631 2019-05-24
36      10510 2019-05-24   10  5.9 1.4   NA  NA   NA     NA      NA  NA   NA     NA   NA    NA   NA  NA   NA eor -2117439060 2019-05-19
        lat     long                    Stationname
2  50.71187 8.706279             Giessen/Wettenberg
7  50.82548 8.892961 Coelbe, Kr. Marburg-Biedenkopf
16 47.77411 9.540569     Weingarten, Kr. Ravensburg
21 48.86810 9.285427      Stuttgart (Schnarrenberg)
29 51.61666 7.950153                           Werl
36 48.87217 9.396229             Winterbach/Remstal

该数据集与您首次在my_df_example.

如果有更多的时间,也许有人会告诉我们如何用tidyverse符号来解决这个问题,因为我怀疑用这个包做子集提取算法会更直接。

于 2020-12-22T14:24:08.170 回答
0

我会建议一个data.table解决方案:

library(data.table)

full = rbindlist(kl) # Convert list to one huge DF
setDT(my_df_final) # Convert your df to DT

new_df <- merge(my_df_final, full, by.x = c("ID", "Datum"), by.y = c("STATIONS_ID", "MESS_DATUM"), all.x = T) # Merge full and your df

new_df
      ID      Datum      lat     long Stations_id                   Stationsname QN_3   FX  FM QN_4 RSK RSKF   SDK
1:  1639 2019-05-10 50.71187 8.706279        1639             Giessen/Wettenberg   10  9.1 3.3    3 9.3    6 4.000
2:  3164 2019-05-01 50.82548 8.892961        3164 Coelbe, Kr. Marburg-Biedenkopf   NA   NA  NA    3 0.0    0    NA
3:  4094 2019-05-03 47.77411 9.540569        4094     Weingarten, Kr. Ravensburg   10  6.4 2.2    3 5.2    4 0.000
4:  4928 2019-04-30 48.86810 9.285427        4928      Stuttgart (Schnarrenberg)   10  7.9 2.7    3 0.0    6 3.583
5: 10510 2019-05-19 48.87217 9.396229       10510             Winterbach/Remstal   10 11.3 1.8   NA  NA   NA    NA
   SHK_TAG  NM  VPM     PM  TMK   UPM  TXK TNK TGK eor
1:      NA 6.6 10.2 985.16 11.1 78.21 15.9 7.7 5.9 eor
2:      NA  NA  9.7     NA 12.3 71.00 20.0 3.2 1.4 eor
3:      NA  NA 10.0     NA  8.7 88.92 11.6 5.3 3.0 eor
4:       0 4.9  9.3 981.55 10.5 75.58 15.3 7.3 3.7 eor
5:      NA  NA   NA     NA   NA    NA   NA  NA  NA eor

(也应该在基础 R 中工作,但这种方式肯定更快)

于 2020-12-22T14:41:47.520 回答