【问题标题】:Efficient manipulation and extraction of data from multiple matrices - means and dates从多个矩阵中高效处理和提取数据 - 均值和日期
【发布时间】:2019-05-14 00:43:40
【问题描述】:

我有一系列大型矩阵,我只是习惯于以这种格式导航它们并使用函数。

我有许多参数的分钟数据,我已经能够将其减少到每日平均值 - 我想将每个平均输出与日期序列对齐,并从那里提取每年的每日平均值。

以单数形式我是这样做的

A <- matrix(c(1:3285),nrow=3)
AA <- sapply(1:1095, function(x) mean(A [,x], na.rm = TRUE))
D <- seq(from = as.Date("2013-01-01"), to = as.Date("2015-12-31"), by= 1)
df <- cbind.data.frame(D,AA)

这让我每列的平均值与 2013-2015 的日期对齐

library(lubridate)
years <- year(as.Date(df$D, "%d-%b-%y"))
day <- yday(as.Date(df$D, "%d-%b-%y"))

 #to get the average of DOY over three years
  avg <- as.data.frame(tapply(df$AA,day, mean, na.rm=T)) #gives average value on day of year 
  #Average for specific DOY for each year
  av <- as.data.frame(tapply(df$AA,list(day,years), mean, na.rm=T)) #gets the DOY average per year

#bind to get yearly averages and overall average in a data frame format
DF <- cbind(av,avg)
head(DF)
colnames(DF)[4] <- "avg" #rename ts average column

现在说我有多个矩阵(所有相同的维度只是不同的参数)我想这样做......有没有一种有效的方法来循环这个所以我得到每个 AC 的数据帧(DF)输出?

 #extra matrices to play with:
 B <- matrix(c(3285:6570),nrow=3)
 C <- matrix(c(6570:9855),nrow=3)

到目前为止,我已经在 stackoverflow 上获得了一些 initial help

#column means for each matrices
vapply(list(A, B, C), colMeans, numeric(1095))

【问题讨论】:

  • 您希望输出的格式是什么?数据框列表?
  • 是的——我认为数据框可以工作——或者另一个矩阵列表——我想对数据做一些进一步的操作并最终用它来绘图——目前我对数据框的效率更高——但是我正在尝试更多地使用矩阵。我发现我的很多代码通常都很冗长且重复,所以我试图尽可能地避免这种情况 - 所以基本上哪个更有效。

标签: r function matrix apply


【解决方案1】:

这是一个tinyverse 解决方案(即没有第三方包),它将您的流程包装在一个函数中,以接收矩阵作为输入并返回数据帧作为输出。然后在矩阵列表上运行lapply

df_process <- function(mat) {
  # CREATE DF AND ADD NEW COLUMNS
  df <-  within(data.frame(D=seq(from = as.Date("2013-01-01"),
                                 to = as.Date("2015-12-31"), by= 1),
                           AA=sapply(1:1095, function(x) mean(mat[,x], na.rm=TRUE))), 
               {
                year <- format(as.Date(df$D, origin="1970-01-01"), "%Y")
                day <- format(as.Date(df$D, origin="1970-01-01"), "%d") 
               })

  # CREATE DF WITH TAPPLY CALLS, RENAME COLUMNS
  df <- setNames(data.frame(tapply(df$AA,list(day,years), mean, na.rm=T),
                            avg = c(tapply(df$AA, day, mean, na.rm=T))), 
                 c("2013", "2014", "2015", "avg"))
}

A <- matrix(c(1:3285),nrow=3)
B <- matrix(c(3286:6570),nrow=3)
C <- matrix(c(6571:9855),nrow=3)

# NAMED LIST OF DATA FRAMES
DF_list <- setNames(lapply(list(A, B, C), df_process), c("A", "B", "C"))

all.equal(DF, DF_list$A)
# [1] TRUE
identical(DF, DF_list$A)
# [1] TRUE

输出

lapply(DF_list, head)
# $A
#     2013   2014   2015    avg
# 01 501.5 1596.5 2691.5 1596.5
# 02 504.5 1599.5 2694.5 1599.5
# 03 507.5 1602.5 2697.5 1602.5
# 04 510.5 1605.5 2700.5 1605.5
# 05 513.5 1608.5 2703.5 1608.5
# 06 516.5 1611.5 2706.5 1611.5

# $B
#      2013   2014   2015    avg
# 01 3786.5 4881.5 5976.5 4881.5
# 02 3789.5 4884.5 5979.5 4884.5
# 03 3792.5 4887.5 5982.5 4887.5
# 04 3795.5 4890.5 5985.5 4890.5
# 05 3798.5 4893.5 5988.5 4893.5
# 06 3801.5 4896.5 5991.5 4896.5

# $C
#      2013   2014   2015    avg
# 01 7071.5 8166.5 9261.5 8166.5
# 02 7074.5 8169.5 9264.5 8169.5
# 03 7077.5 8172.5 9267.5 8172.5
# 04 7080.5 8175.5 9270.5 8175.5
# 05 7083.5 8178.5 9273.5 8178.5
# 06 7086.5 8181.5 9276.5 8181.5

【讨论】:

    【解决方案2】:

    这是tidyverse 解决方案。让

    dates <- seq(from = as.Date("2013-01-01"), to = as.Date("2015-12-31"), by = 1)
    A <- data.frame(matrix(c(1:3285), ncol = 3, byrow = TRUE))
    

    因为我知道所有矩阵的日期都相同。另外,我将A 设为长而不是宽,这在使用tidyverse 时会更好。那么也许你更喜欢

    形式的输出
    A %>% group_by(year = year(dates), day = yday(dates)) %>% 
      summarise(dayYearAvg = mean(c(X1, X2, X3))) %>%
      group_by(day) %>% mutate(dayAvg = mean(dayYearAvg))
    # A tibble: 1,095 x 4
    # Groups:   day [365]
    #     year   day dayYearAvg dayAvg
    #    <dbl> <dbl>      <dbl>  <dbl>
    #  1  2013     1          2   1097
    #  2  2013     2          5   1100
    #  3  2013     3          8   1103
    #  ...
    

    如果没有,我们会得到与您的示例相同的结果

    A %>% group_by(year = year(dates), day = yday(dates)) %>% 
      summarise(dayYearAvg = mean(c(X1, X2, X3))) %>%
      group_by(day) %>% mutate(dayAvg = mean(dayYearAvg)) %>%
      spread(year, dayYearAvg) %>% ungroup %>% select(-day)
    # A tibble: 365 x 4
    #    dayAvg `2013` `2014` `2015`
    #     <dbl>  <dbl>  <dbl>  <dbl>
    #  1   1097      2   1097   2192
    #  2   1100      5   1100   2195
    #  3   1103      8   1103   2198
    #  4   1106     11   1106   2201
    #  ...
    

    现在让我们也

    B <- data.frame(matrix(c(3285:6569), ncol = 3, byrow = TRUE))
    C <- data.frame(matrix(c(6570:9854), ncol = 3, byrow = TRUE))
    l <- list(A, B, C)
    

    这给了

    map(l, . %>% group_by(year = year(dates), day = yday(dates)) %>% 
          summarise(dayYearAvg = mean(c(X1, X2, X3))) %>%
          group_by(day) %>% mutate(dayAvg = mean(dayYearAvg)) %>%
          spread(year, dayYearAvg) %>% ungroup %>% select(-day))
    # [[1]]
    # A tibble: 365 x 4
    #    dayAvg `2013` `2014` `2015`
    #     <dbl>  <dbl>  <dbl>  <dbl>
    #  1   1097      2   1097   2192
    #  2   1100      5   1100   2195
    #  ...
    # [[2]]
    # A tibble: 365 x 4
    #    dayAvg `2013` `2014` `2015`
    #     <dbl>  <dbl>  <dbl>  <dbl>
    #  1   4381   3286   4381   5476
    #  2   4384   3289   4384   5479
    #  ...
    # [[3]]
    # A tibble: 365 x 4
    #    dayAvg `2013` `2014` `2015`
    #     <dbl>  <dbl>  <dbl>  <dbl>
    #  1   7666   6571   7666   8761
    #  2   7669   6574   7669   8764
    #  ...
    

    【讨论】:

      猜你喜欢
      • 2018-08-18
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 2014-08-07
      • 2018-03-16
      • 2016-11-14
      • 2012-05-06
      • 1970-01-01
      相关资源
      最近更新 更多