【问题标题】:Argument is not numeric or logical with function rollapply, followed by NAs introduced by coercion参数不是数字或逻辑函数 rollapply,后跟强制引入的 NA
【发布时间】:2019-01-25 13:43:49
【问题描述】:

我正在尝试计算基于 10 分钟数据的数据框中的每 3 个观察值,我试图将其平均到半小时。我的数据如下所示:

    Date             Value
2017-09-20 09:19:59 96.510
2017-09-20 09:30:00 113.290
2017-09-20 09:40:00 128.370
2017-09-20 09:50:00 128.620
2017-09-20 10:00:00 94.080
2017-09-20 10:10:00 208.150
2017-09-20 10:20:00 178.820
2017-09-20 10:30:00 208.440
2017-09-20 10:40:00 285.490
2017-09-20 10:49:59 305.020

我首先尝试使用 zoo 包 library (zoo) 中的函数 rollapply 按以下方式计算均值:

means <- rollapply(df, by=3, 3, FUN=mean)

但是,我收到了 50 条警告:

在 mean.default(data[posns], ...) 中:参数不是数字或 逻辑:返回 NA

我检查了我的课程,值(数字)和日期是一个因素。然后我尝试通过以下方式将日期(因子)转换为日期类:

`df$Date <- as.Date(df, format = "%Y-%m-%d %H:%m:%s")` and

df$Date <- strptime(time,"%Y-%m-%d %H:%M:%S",tz="GMT") and still didn't work.

我也试过用聚合来计算均值,但还是不行。

library(chron)
aggregate(chron(times=Date) ~ Value, data=df, FUN=mean)

我得到了:

convert.times(times., fmt) 中的错误:格式 h:m:s 可能不正确 另外:警告消息:在 convert.times(times., fmt) : NAs 强制引入

此时我很绝望,很抱歉在这里问。也许我的数据有问题,因为它首先是一个 xlxs 文件,我将奇怪的 excel 时间转换为 R 中的日期,但仍然......我想知道,因为这是因为某些日期的末尾有 :59 秒.如果有帮助,我也可以在线发布我的全部数据。非常感谢!

【问题讨论】:

    标签: r dataframe aggregate coercion rollapply


    【解决方案1】:

    问题中的代码将 df 强制转换为一个矩阵,将其转换为字符矩阵,然后尝试对两列中的每一列进行滚动平均值,这两个列都是字符。

    如果您使用时间序列表示,那就容易多了。数据框确实不适合表示时间序列,因为您一直在协调时间列和数据,而如果您将其表示为将自动处理的动物园对象。

    首先将df 转换为动物园系列,然后运行rollapplyr。可选择将其转换回数据框或将其保留为动物园对象。

    library(zoo)
    
    z <- read.zoo(df)
    Value <- rollapplyr(z, 3, by = 3, mean)
    # fortify.zoo(Value)
    

    如果你想用管道来表达,那么试试这个:

    library(magrittr)
    library(zoo)
    
    Value <- df %>% read.zoo %>% rollapplyr(3, by = 3, mean)
    

    注意

    使用的输入 df 以可重现的形式是:

    df <-
    structure(list(Date = structure(c(1505913599, 1505914200, 1505914800, 
    1505915400, 1505916000, 1505916600, 1505917200, 1505917800, 1505918400, 
    1505918999), class = c("POSIXct", "POSIXt"), tzone = ""), Value = c(96.51, 
    113.29, 128.37, 128.62, 94.08, 208.15, 178.82, 208.44, 285.49, 
    305.02)), class = "data.frame", row.names = c(NA, -10L))
    

    【讨论】:

    • 我最近了解到包zoo,它帮助我想出了我给出的答案。看来zoo 比我想象的要强大得多。肯定会调查细节。很好的答案!
    • 也非常感谢您的解决方案!我有点难过,因为我多次使用 zoo 来获取另一个数据(最初是 csv 而不是 xlsx,我真的很喜欢这个包)但是警告仍然存在(它仍然会返回 NAs)。我认为数据和我从 xlsx 到 csv 时间的时间转换有些奇怪(因为如果我没记错的话,xlsx 中的天数是从 1899 年开始计算的)。还是谢谢你!它适用于您下面的答案!
    • 如果您需要帮助,您需要提供一个可重现的示例,如果您的数据有问题,您需要弄清楚它是什么,而不是试图通过运行随机代码来避免它。据您所知,问题仍然存在。
    【解决方案2】:

    主要问题是您尝试将rollapply 与数据框而不是单列或向量一起使用。如果我正确理解您的目标,以下应该可以完成工作:

    library(dplyr)
    library(zoo)
    
    df %>%
      # compute rolling means with a window width of 3
      mutate(means = rollmeanr(Value, k = 3, fill = NA)) %>%
      # decrease the frequency in accordance with the window width
      filter(seq_len(nrow(df)) %% 3 == 0) # or alternatively, slice(seq(3, nrow(df), 3))
    
    # # A tibble: 3 x 3
    #   Date                Value means
    #   <dttm>              <dbl> <dbl>
    # 1 2017-09-20 09:40:00  128.  113.
    # 2 2017-09-20 10:10:00  208.  144.
    # 3 2017-09-20 10:40:00  285.  224.
    

    数据:

    df <- structure(list(Date = structure(c(1505917199, 1505917800, 1505918400, 
    1505919000, 1505919600, 1505920200, 1505920800, 1505921400, 1505922000, 
    1505922599), class = c("POSIXct", "POSIXt"), tzone = ""), Value = c(96.51, 
    113.29, 128.37, 128.62, 94.08, 208.15, 178.82, 208.44, 285.49, 
    305.02)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", 
    "data.frame"))
    

    【讨论】:

    • 成功了!我不知道为什么,但它没有再次与@G一起工作。 Grothendieck 解决方案,不过我也很欣赏他的回答。但是,您的解决方案有效,感谢您抽出宝贵时间。
    猜你喜欢
    • 2013-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 2022-06-20
    • 2020-11-16
    • 2018-08-11
    • 2021-01-29
    相关资源
    最近更新 更多