首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >R填充NAs取决于NAs之后的值以及有多少NAs

R填充NAs取决于NAs之后的值以及有多少NAs
EN

Stack Overflow用户
提问于 2019-08-13 10:53:05
回答 3查看 90关注 0票数 1

您好,我想根据NAs之后的第一个数字和有多少个NAs来填充我的data.frame中的NAs。这是降雨量数据,NAs显示该测量仪没有通信的时间,但我们知道这段时间内发生的总降雨量,并希望对其进行平均。

这里有很多关于如何填充它们的问题,但我还没有找到任何需要使用NAs数量的问题。基本上,我希望将NAs之后的数字的值除以丢失的时间步数的平均值。

以下是我的示例数据。我已经让它变得非常简单,但在真实的示例中,我有数十万个条目,并将按站点对数据进行分组。

代码语言:javascript
运行
复制
library(tidyr)
library(dplyr)
library(zoo) 
testdf <- data.frame(DateTime = seq.POSIXt(
  from = as.POSIXct("2019-01-01"), to =  as.POSIXct("2019-01-02"), by = "hours"),
  Value = c(0,0,1,NA,NA,NA,-4,0,0,0,NA,NA,NA,NA,NA,-2,5,3,NA,-2,0,0,0,1,2))

使用tidyr::fillzoo:na.locf后,我可以很容易地用第一个值填充NAs

代码语言:javascript
运行
复制
tidyr::fill(testdf,Value, .direction = "up")

testdf %>% mutate(Filled = zoo::na.locf(Value, fromLast = T))

但我想将其除以一行中出现的NAs数加1(即,如果有5个NAs除以6)。理想情况下,我还希望更改NAs之后的值,使其也等于这个新值,但如果需要的话,我可能可以为这一步修改一些东西。

加分如果有一种简单的方法可以只对某些时期的空档(基本上是na.locf的最大间隔特性)这样做,就好像我有一两个小时没有平均,但如果是一周或一个月,我想把它留为NA。

输出示例

代码语言:javascript
运行
复制
desiredOutput <- data.frame(DateTime = seq.POSIXt(
  from = as.POSIXct("2019-01-01"), to =  as.POSIXct("2019-01-02"), by = "hours"),
  Value = c(0,0,1,-1,-1,-1,-1,0,0,0,-0.33,-0.33,-0.33,-0.33,-0.33,-0.33,5,3,-1,-1,0,0,0,1,2))
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-08-13 11:22:57

我们可以使用data.table。按值中非NA元素的值的累积和分组,将值‘shift’除以行数,并赋值(:=)以更新‘last’列

代码语言:javascript
运行
复制
library(data.table)
setDT(testdf)[,  Value := last(Value)/.N, shift(cumsum(!is.na(Value)), fill = 1)]
testdf
#               DateTime      Value
# 1: 2019-01-01 00:00:00  0.0000000
# 2: 2019-01-01 01:00:00  0.0000000
# 3: 2019-01-01 02:00:00  1.0000000
# 4: 2019-01-01 03:00:00 -1.0000000
# 5: 2019-01-01 04:00:00 -1.0000000
# 6: 2019-01-01 05:00:00 -1.0000000
# 7: 2019-01-01 06:00:00 -1.0000000
# 8: 2019-01-01 07:00:00  0.0000000
# 9: 2019-01-01 08:00:00  0.0000000
#10: 2019-01-01 09:00:00  0.0000000
#11: 2019-01-01 10:00:00 -0.3333333
#12: 2019-01-01 11:00:00 -0.3333333
#13: 2019-01-01 12:00:00 -0.3333333
#14: 2019-01-01 13:00:00 -0.3333333
#15: 2019-01-01 14:00:00 -0.3333333
#16: 2019-01-01 15:00:00 -0.3333333
#17: 2019-01-01 16:00:00  5.0000000
#18: 2019-01-01 17:00:00  3.0000000
#9: 2019-01-01 18:00:00 -1.0000000
#20: 2019-01-01 19:00:00 -1.0000000
#21: 2019-01-01 20:00:00  0.0000000
#22: 2019-01-01 21:00:00  0.0000000
#23: 2019-01-01 22:00:00  0.0000000
#24: 2019-01-01 23:00:00  1.0000000
#25: 2019-01-02 00:00:00  2.0000000
票数 1
EN

Stack Overflow用户

发布于 2019-08-13 11:09:19

使用dplyr的一种方法是创建组,以便将连续NA之后的第一个非NA值包含在组中,这样我们就可以将last(Value)除以组中的行数(n())。non-NA的值存储在各自的组中,只有一个元素,因此它们的计算不受影响,非NA number返回相同的数字。

代码语言:javascript
运行
复制
library(dplyr)

testdf %>%
   group_by(group = lag(cumsum(!is.na(Value)), default = 1)) %>%
   mutate(Value = last(Value)/n()) %>%
   ungroup %>%
   select(-group)

# A tibble: 25 x 2
#   DateTime            Value
#   <dttm>              <dbl>
# 1 2019-01-01 00:00:00     0
# 2 2019-01-01 01:00:00     0
# 3 2019-01-01 02:00:00     1
# 4 2019-01-01 03:00:00    -1
# 5 2019-01-01 04:00:00    -1
# 6 2019-01-01 05:00:00    -1
# 7 2019-01-01 06:00:00    -1
# 8 2019-01-01 07:00:00     0
# 9 2019-01-01 08:00:00     0
#10 2019-01-01 09:00:00     0
# … with 15 more rows

为了包含maxgap功能,我们可以用第一个Datetime减去最后一个,如果它大于某个值,就用NA replace它,例如下面我做了10个小时的持续时间。

代码语言:javascript
运行
复制
testdf %>%
   group_by(group = lag(cumsum(!is.na(Value)), default = 1)) %>%
   mutate(Value = last(Value)/n(), 
          Value = replace(Value, as.integer(difftime(DateTime[max(n() - 1, 1)],
                  first(DateTime), units = "hours")) > 10, NA))
票数 2
EN

Stack Overflow用户

发布于 2020-12-30 01:07:16

这可能很难适应这里非常具体的细节,但通常情况下,imputeTS包中的na_ma移动平均估算函数可以帮助您将NAs替换为缺失值周围的非NA值的平均值。它还具有必需的maxgap选项。

你可以直接打电话给

代码语言:javascript
运行
复制
library("imputeTS")
na_ma(x, k = 4, weighting = "simple", maxgap = 5)

这将用最接近的4个值(左侧4个,右侧4个)的平均值替换NA值。使用您定义的maxgap =5,连续运行的NAs的长度超过5的将保留为NA。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57470549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档