Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
根据R中另一列的日期范围查找该列的平均值_R_Date_Average_Na - Fatal编程技术网

根据R中另一列的日期范围查找该列的平均值

根据R中另一列的日期范围查找该列的平均值,r,date,average,na,R,Date,Average,Na,我有两个数据帧,如下所示: > head(y,n=4) Source: local data frame [6 x 3] Start Date End Date Length 1 2006-06-08 2006-06-10 3 2 2006-06-12 2006-06-14 3 3 2006-06-18 2006-06-21 4 4 2006-06-24 2006-06-25 2 及 我正在寻找一种在数据框y中添加新

我有两个数据帧,如下所示:

> head(y,n=4)
Source: local data frame [6 x 3]

  Start Date   End Date   Length

1 2006-06-08 2006-06-10        3
2 2006-06-12 2006-06-14        3
3 2006-06-18 2006-06-21        4
4 2006-06-24 2006-06-25        2

我正在寻找一种在数据框y中添加新列的方法,该列将显示数据框x的平均组大小(四舍五入到最接近的整数),具体取决于y中提供的给定开始日期和结束日期

例如,在y的第一行中,我有6/8/06到6/10/06。这是一个3天的长度,因此我希望新列的数字为2,因为对应的Group.Size值在数据框x中分别为3、1和3(平均值=2.33,四舍五入到最接近的整数为2)

如果我的DATAFRAM X中有NA,我想把它看作是0。


这项任务涉及多个步骤,可能有一种简单的方法。。。我对R比较陌生,很难把它分解。请告诉我是否应该澄清我的示例。

这是一个适用于数据框
y
行的解决方案:

library(dplyr)
get_mean_size <- function(start, end, length) {
   s <- sum(filter(x, Date >= start, Date <= end)$Group.Size, na.rm = TRUE)
   round(s/length)
}
y$Mean.Size = Map(get_mean_size, y$Start_Date, y$End_Date, y$Length)
y
##   Start_Date   End_Date Length Mean.Size
## 1 2006-06-08 2006-06-10      3         2
## 2 2006-06-12 2006-06-14      3         5
## 3 2006-06-18 2006-06-21      4         6
## 4 2006-06-24 2006-06-25      2         0
如果它们没有class
Date
,可以使用

x$Date <- as.Date(x$Date)

x$Date有很多方法,但这里有一种。我们可以首先使用
lappy
创建日期位置列表(序号:确保日期按时间顺序排列)。然后我们将函数
round(mean(Group.Size))
映射到每个值:

lst <- lapply(y[1:2], function(.x) match(.x, x[,"Date"]))
y$avg <- mapply(function(i,j) round(mean(x$Group.Size[i:j], na.rm=TRUE)), lst[[1]],lst[[2]])
y
#    StartDate    EndDate Length avg
# 1 2006-06-08 2006-06-10      3   2
# 2 2006-06-12 2006-06-14      3   8
# 3 2006-06-18 2006-06-21      4   6
# 4 2006-06-24 2006-06-25      2   0

lst假设
x$Date
y$StartDate
y$EndDate
属于
Date
(或
字符
)类,下面的
应用
方法应该起作用:

 y$AvGroupSize<- apply(y, 1, function(z) {
                 round(mean(x$Group.Size[which(x$Date >= z[1] & x$Date <=z[2])], na.rm=T),0)
    }
)
y$AvGroupSize=z[1]&x$Date
#用0替换x中缺少的值

x[is.na(x)]这里有一个不同的
dplyr
解决方案

library(dplyr)

na2zero <- function(x) ifelse(is.na(x),0,x) # Convert NA to zero
ydf %>%
    group_by(Start_Date, End_Date) %>%
    mutate(avg = round(mean(na2zero(xdf$Group.Size[ between(xdf$Date, Start_Date, End_Date) ])), 0)) %>%
    ungroup

##   Start_Date   End_Date Length   avg
##       (time)     (time)  (int) (dbl)
## 1 2006-06-08 2006-06-10      3     2
## 2 2006-06-12 2006-06-14      3     5
## 3 2006-06-18 2006-06-21      4     6
## 4 2006-06-24 2006-06-25      2     0
库(dplyr)
na2zero%
分组依据(开始日期、结束日期)%>%
变异(平均值=四舍五入(平均值(na2zero(xdf$组大小[介于(xdf$日期、开始日期、结束日期)]),0))%>%
解组
##开始日期结束日期长度平均值
##(时间)(时间)(整数)(dbl)
## 1 2006-06-08 2006-06-10      3     2
## 2 2006-06-12 2006-06-14      3     5
## 3 2006-06-18 2006-06-21      4     6
## 4 2006-06-24 2006-06-25      2     0

完全正确。我注意到并做了必要的修改。谢谢。这个很好用。你介意走过你的台阶吗?我试着介绍一下你对函数(z)所做的事情@Submartingaleth不会将
NA
视为零。@Stibu是的,你是对的。它忽略NAs,而不是将其替换为0。将NAs视为0很简单,方法是在顶部添加一行:
x$Group.SizeMy输出正确。我的解决方案与您提出的解决方案之间的区别在于
mean
with
na.rm=TRUE
将在计算平均值时忽略
na
值,而OP要求将
na
视为零。另外,我决定使用
length
,因为可能会缺少日期。
 y$AvGroupSize<- apply(y, 1, function(z) {
                 round(mean(x$Group.Size[which(x$Date >= z[1] & x$Date <=z[2])], na.rm=T),0)
    }
)
#Replace missing values in x with 0
x[is.na(x)] <- 0

#Create new 'Group' variable and loop through x to create groups 
x$Group <-1
j <- 1
for(i in 1:nrow(x)){
  if(x[i,"Date"]==y[j,"StartDate"]){
    x[i,"Group"] <- j+1
    if(j<nrow(y)){
      j <- j+1
    } else{
      j <- j 
    }
  }else if(i>1){
    x[i,"Group"] <- x[i-1,"Group"]
  }else {
    x[i,"Group"] <- 1
  }
}

#Use tapply function to get the rounded mean of each Group
tapply(x$Group.Size, x$Group, function(z) round(mean(z)))
library(dplyr)

na2zero <- function(x) ifelse(is.na(x),0,x) # Convert NA to zero
ydf %>%
    group_by(Start_Date, End_Date) %>%
    mutate(avg = round(mean(na2zero(xdf$Group.Size[ between(xdf$Date, Start_Date, End_Date) ])), 0)) %>%
    ungroup

##   Start_Date   End_Date Length   avg
##       (time)     (time)  (int) (dbl)
## 1 2006-06-08 2006-06-10      3     2
## 2 2006-06-12 2006-06-14      3     5
## 3 2006-06-18 2006-06-21      4     6
## 4 2006-06-24 2006-06-25      2     0