【问题标题】:Select dates based in certain criteria in a dataframe根据数据框中的某些条件选择日期
【发布时间】:2021-08-18 17:50:13
【问题描述】:

我有一个由 4 列组成的数据框,其中包含来自 3 个不同位置、来自不同时期的温度数据 rbind - 在单个数据框中。我想从 3 个站点中选择 温度,它们是共同的日期/时间(小时)。

下面我提供了一个可重现的例子:

a1 <- seq.POSIXt(as.POSIXct("1995-01-01"), as.POSIXct("2007-04-01"), by = "120 min")
a2 <- seq.POSIXt(as.POSIXct("1998-04-19"), as.POSIXct("2004-03-20"), by = "60 min")
a3 <- seq.POSIXt(as.POSIXct("1991-01-01"), as.POSIXct("2001-04-01"), by = "180 min")


t1 <- runif(length(a1), min = -5, max = 45)
t2 <- runif(length(a2), min = -5, max = 45)
t3 <- runif(length(a3), min = -5, max = 45)


station1 <- data.frame(date = a1, temp = t1, ID = "station1")
station2 <- data.frame(date = a2, temp = t2, ID = "station2")
station3 <- data.frame(date = a3, temp = t3, ID = "station3")

all_stat <- rbind(station1,station2,station3)


all_stat <- all_stat %>%
  mutate(time = hms::as_hms(date),
         date = as_date(date)) %>%
  relocate(date, time)

理想情况下,我希望在这 3 个站点中拥有 临时数据的常见日期/小时的四列数据框(日期/时间/临时/ID)。我用dplyrsubset 尝试了多种方法,但没有任何效果。

【问题讨论】:

    标签: r datetime filter dplyr


    【解决方案1】:

    我们可以在tidyverse 中做到这一点。

    library(dplyr)   
    library(stringr)
    all_stat %>%       
        group_by(datetime = str_c(date, time)) %>%
        filter(n_distinct(ID) == n_distinct(all_stat$ID))
    

    或者如果我们想让这个速度更快,请使用data.table

    library(data.table)
    setDT(all_stat)[, datetime := paste(date, time)]
    sub_stat <- all_stat[all_stat[, .I[uniqueN(ID) == uniqueN(all_stat$ID)],
                 by = datetime]$V1]
    

    【讨论】:

    • 亲爱的@akrun,在这里的示例中,您的解决方案运行良好,但是当我将其应用于我的真实数据时,我收到以下消息:错误:在group_by() 中添加计算列时出现问题。 x mutate()datetime 有问题。我datetime = str_c(date, time) %&gt;% filter(Df_All_stat(ID) == n_distinct(Df_All_stat$ID))。 x 没有适用于“字符”类对象的“过滤器”方法
    • @H.Johnson 我认为我的线路是filter(n_distinct(ID) == n_distinct(all_stat$ID)) 而不是filter(Df_All_stat(ID) == n_distinct(Df_All_stat$ID))
    • @H.Johnson 您将对象名称应用为函数Df_All_stat(
    • 是的,你是对的@akrun,将变量的名称替换为函数是我的错误。现在我正在用我的真实数据运行你给我的脚本,我会提供反馈!
    • 是的,它要快得多,尽管我会坚持使用 dplyr 解决方案,因为它更容易!非常感谢您花时间和精力帮助我!!
    【解决方案2】:

    结合datetime 来创建日期时间列。 split 每个IDdatetime 变量,并使用Reduce 查找公共变量,并使用它对数据帧进行子集化,以仅保留所有ID 之间的公共日期和时间。

    all_stat$datetime <- paste(all_stat$date, all_stat$time)
    result <- subset(all_stat, datetime %in% 
                        Reduce(intersect, split(all_stat$datetime, all_stat$ID)))
    

    【讨论】:

    • 完美运行!感谢您在解释中如此分析!
    猜你喜欢
    • 2020-10-01
    • 2016-10-17
    • 1970-01-01
    • 2017-12-15
    • 2021-04-23
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多