取使用为每行

时间:2018-03-10 19:31:06

标签: r dplyr

我可以使用sapply执行以下操作,但我想如果dplyr也可以这样做,或者如果它是dplyr范围之外的问题。

我有三列,一列有日期(日期),一列有日期间隔(间隔),第三列有数值(值)。

我想要做的是每一行:

1)获取值Date

2)查看日期存在的时间间隔(%间隔内的日期%),并生成相应的布尔矢量

3)使用此布尔向量对整个原始数据帧进行子集化

4)取这个数据帧的值的平均值

5)将值存储在名为mean_for_Date

的新列中

对于以下输入,列mean_for_Date的值将为3和1:

library(lubridate)
library(dplyr)
df <- data.frame( Date = as.Date(c("1998-01-02", "1998-01-06")), Values =  c(1, 3))
df$Intervals <- c(interval(df[2, "Date"] - days(2), df[2, "Date"] + days(2)), interval(df[1, "Date"] - days(2), df[1, "Date"] + days(2))) 

在sapply中,我这样做了:

df$mean_for_Date <- sapply(df$Date, function (x) mean(df$Values[x %within% df$Intervals], na.rm = T))

提前感谢所有可能的建议

3 个答案:

答案 0 :(得分:2)

可以使用dummy列在数据框cartesian join的每一行之间应用df以使其与itsefl自我加入,从而实现一种解决方案。

在准备加入时,我已经删除了一些不需要的列。笛卡尔联接提供DateIntervals的所有可能组合。我将ValuesInterval保持一致,以便在Date匹配时,可以采用相应的Values

IsFound决定Datewithin间隔的行。我们只需filter IsFoundValues为真,因为mean的那些行将在该日期派生Date

如果在多个Interval中找到group_by,该解决方案将有效。 mean最终有助于找到 library(dplyr) df %>% select(-Values, - Intervals) %>% mutate(dummy = 1) %>% inner_join(select(df, -Date) %>% mutate(dummy = 1), by="dummy") %>% mutate(IsFound = Date %within% Intervals) %>% filter(IsFound) %>% select(-dummy, - IsFound) %>% group_by(Date) %>% summarise(Mean = mean(Values)) # A tibble: 2 x 2 # Date Mean # <date> <dbl> #1 1998-01-02 3.00 #2 1998-01-06 1.00

Static methods in interface require -target:jvm-1.8

答案 1 :(得分:2)

dplyr::mutate中的{p> purrr::map_dbltidyverse可以执行相同的操作

library(lubridate) # date
library(magrittr)  # %>% and %<>%
library(tidyverse) # mutate and map_dbl

df <- data.frame( Date = as.Date(c("1998-01-02", "1998-01-06")), Values =  c(1, 3))
df$Intervals <- c(interval(df[2, "Date"] - days(2), df[2, "Date"] + days(2)), 
                  interval(df[1, "Date"] - days(2), df[1, "Date"] + days(2))) 

df %<>%
  mutate(mean_for_Date = map_dbl(Date, ~ mean(Values[. %within% Intervals], na.rm = TRUE)))
df

#>         Date Values                      Intervals mean_for_Date
#> 1 1998-01-02      1 1998-01-04 UTC--1998-01-08 UTC             3
#> 2 1998-01-06      3 1997-12-31 UTC--1998-01-04 UTC             1

str(df)
#> 'data.frame':    2 obs. of  4 variables:
#>  $ Date         : Date, format: "1998-01-02" "1998-01-06"
#>  $ Values       : num  1 3
#>  $ Intervals    :Formal class 'Interval' [package "lubridate"] with 3 slots
#>   .. ..@ .Data: num  345600 345600
#>   .. ..@ start: POSIXct, format: "1998-01-04" ...
#>   .. ..@ tzone: chr "UTC"
#>  $ mean_for_Date: num  3 1

reprex package(v0.2.0)创建于2018-03-10。

答案 2 :(得分:0)

也许我太简单地看到问题了?如果日期落在区间内,这会得到平均值(作为日期的函数)吗?

 df <- df %>% 
          left_join(df %>% 
                       filter(Date %within% Intervals & !is.na(Values)) %>% 
                       group_by(Date) %>% 
                       summarise(mean_for_Date = mean(Values)) %>% 
                       select(Date,mean_for_Date)), by="Date")