2012-07-28 70 views
2

我是R新手,我在寻找类似的问题,但无法找到一个修复我的,任何帮助将不胜感激。R ifelse条件:连续不断的频率不适用

我有一个数据帧L:

  date value 
1 182-2002-01-01 23.95 
2 182-2002-01-02 17.47 
3 182-2002-01-03 NA 
4 183-2002-01-01 NA 
5 183-2002-01-02 5.50 
6 183-2002-01-03 17.02 

我需要做的是:如果有小于5 NA(连续),我只会重复以前的数(17.47),如果有连续超过5个NA,我将需要删除整个月份。

我尝试过很多次功能,但没有工作,非常感谢您的帮助。

+0

欢迎来到Stack Overflow!如果你花时间让问题重现,你会发现你会得到更好的答案。请遵循指南(http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example),特别注意关于'dput()'的部分。谢谢! – 2012-07-28 02:45:58

回答

2

为了演示的目的,我将稍微调整一下你的问题。 我打算给你使用一个类似的数据集,但连续使用2个NA。这很容易推广到5,不用担心。我还打算使用的数据集,更好地体现了解

所以首先,如何让你的数据是什么样子,我要使用:

library(reshape) 
M2<-data.frame(colsplit(M$date, "-", c("ID", "year", "month", "day")), 
       value=M$value) 

这才叫出来的路,这是我要与之合作的数据:

library(reshape) 
M2<-data.frame(colsplit(M$date, "-", c("ID", "year", "month", "day")), 
       value=M$value) 

set.seed(1234) 
M2<-expand.grid(ID=182, year=2002:2004, month=1:2, day=1:3, KEEP.OUT.ATTRS=FALSE) 
M2 <- M2[with(M2, order(year, month, day, ID)),] #sort the data 
M2$value <- sample(c(NA, rnorm(100)), nrow(M2), 
        prob=c(0.5, rep(0.5/100, 100)), replace=TRUE) 
M2 

    ID year month day  value 
1 182 2002  1 1 -0.5012581 
7 182 2002  1 2 1.1022975 
13 182 2002  1 3   NA 
4 182 2002  2 1 -0.1623095 
10 182 2002  2 2 1.1022975 
16 182 2002  2 3 -1.2519859 
2 182 2003  1 1   NA 
8 182 2003  1 2   NA 
14 182 2003  1 3   NA 
5 182 2003  2 1 0.9729168 
11 182 2003  2 2 0.9594941 
17 182 2003  2 3   NA 
3 182 2004  1 1   NA 
9 182 2004  1 2 -1.1088896 
15 182 2004  1 3 0.9594941 
6 182 2004  2 1 -0.4027320 
12 182 2004  2 2 -0.0151383 
18 182 2004  2 3 -1.0686427 

首先,我们要去掉其中,在一个月内,有2个或多个NAS行中的所有情况:

NA_run <- function(x, maxlen){ 
    runs <- rle(is.na(x$value)) 
    if(any(runs$lengths[runs$values] >= maxlen)) NULL else x 
    } 

library(plyr) 
rem <- ddply(M2, .(ID, year, month), NA_run, 2) 
rem 

    ID year month day  value 
1 182 2002  1 1 -0.5012581 
2 182 2002  1 2 1.1022975 
3 182 2002  1 3   NA 
4 182 2002  2 1 -0.1623095 
5 182 2002  2 2 1.1022975 
6 182 2002  2 3 -1.2519859 
7 182 2003  2 1 0.9729168 
8 182 2003  2 2 0.9594941 
9 182 2003  2 3   NA 
10 182 2004  1 1   NA 
11 182 2004  1 2 -1.1088896 
12 182 2004  1 3 0.9594941 
13 182 2004  2 1 -0.4027320 
14 182 2004  2 2 -0.0151383 
15 182 2004  2 3 -1.0686427 

您可以看到连续两个NDA中的两个已被删除。剩下的那个是因为它属于两个不同的月份。现在我们要填写剩余的NAs。如果他们在一开始就是正确的(这是你想要的,我认为),那么na.rm=FALSE的论点就是为了保持新生。

library(zoo) 
rem$value <- na.locf(rem$value, na.rm=FALSE) 
rem 

    ID year month day  value 
1 182 2002  1 1 -0.5012581 
2 182 2002  1 2 1.1022975 
3 182 2002  1 3 1.1022975 
4 182 2002  2 1 -0.1623095 
5 182 2002  2 2 1.1022975 
6 182 2002  2 3 -1.2519859 
7 182 2003  2 1 0.9729168 
8 182 2003  2 2 0.9594941 
9 182 2003  2 3 0.9594941 
10 182 2004  1 1 0.9594941 
11 182 2004  1 2 -1.1088896 
12 182 2004  1 3 0.9594941 
13 182 2004  2 1 -0.4027320 
14 182 2004  2 2 -0.0151383 
15 182 2004  2 3 -1.0686427 

现在,所有你需要做的,使这5个或更多与您的数据是在NA_runmaxlen参数的值更改为5

编辑:另外,如果你不想值从前几个月复制:

library(zoo) 
rem$value <- ddply(rem, .(ID, year, month), summarise, 
        value=na.locf(value, na.rm=FALSE))$value 
rem 

    ID year month day  value 
1 182 2002  1 1 -0.5012581 
2 182 2002  1 2 1.1022975 
3 182 2002  1 3 1.1022975 
4 182 2002  2 1 -0.1623095 
5 182 2002  2 2 1.1022975 
6 182 2002  2 3 -1.2519859 
7 182 2003  2 1 0.9729168 
8 182 2003  2 2 0.9594941 
9 182 2003  2 3 0.9594941 
10 182 2004  1 1   NA 
11 182 2004  1 2 -1.1088896 
12 182 2004  1 3 0.9594941 
13 182 2004  2 1 -0.4027320 
14 182 2004  2 2 -0.0151383 
15 182 2004  2 3 -1.0686427 
+0

完美的作品,非常感谢!顺便说一句,我有另一个条件说,如果缺失的天数在2-4天之间,我需要做一个线性插值,这是我试过的:NA_run < - 函数(x,maxlen)运行< - rle(是。na(x $ value)) miss < - runs $ lengths [runs $ values] ifelse(miss> = maxlen,NULL, ifelse((miss> maxlen-3)&(miss Rosa 2012-07-30 21:30:03

+0

这完全是一个不同的问题,但我要做的是设置'na.locf'将最大NA填充到1,然后用'rle'来计算剩余NA运行的指数。找到前后的索引和运行,并对这些进行线性插值。 – 2012-07-31 01:09:56

+0

我打算尝试一个更简单的例子,但似乎使它更复杂。 :p我需要做的是说如果连续少于5个NA,重复先前的数据,如果5到10 NA,做线性插值,但是如果超过10个NA,删除月份。你的代码对于这两部分工作得非常好,但我对这个评论感到困惑,你的意思是从头再来一遍还是只对NA_run做出改变?非常感谢你! – Rosa 2012-07-31 02:36:12

0

我做这两个步骤:

  1. rlerollapplyshift基于战略,以填补小间隙(少于5倍的NA一排)。
  2. A by,aggregateddply为基础的战略采取任何一个月与步骤1后保留的神经网络,并使整个月NA。
+0

感谢您的编辑和建议,:) – Rosa 2012-07-30 21:32:33