Dplyr条件逻辑计数行数

Posted

技术标签:

【中文标题】Dplyr条件逻辑计数行数【英文标题】:Dplyr conditional logic count number of rows 【发布时间】:2018-02-28 16:52:34 【问题描述】:

您好,我正在尝试计算我的数据集中出现的实例。这是一个非常大的数据集。

示例如下:

     visitid   procedureid  collectiondatetime source status
     100       100.644      2016-12-03 17:20:00      N   COMP
     100       100.644      2017-09-21 12:00:00     RS   COMP
     100       100.644      2017-08-25 15:48:00      N   COMP
     100       100.644      2017-09-01 12:00:00     RS   COMP
     100       100.644      2017-08-23 10:31:00      N    CAN
     200       100.644      2017-09-01 14:00:00      N   COMP

我想确定在访问期间是否取消了某个程序(状态 = CAN),如果来自同一来源的相同程序在以后重复并完成(状态 = COMP)。 我想总结一下这种情况发生的次数,以确定这些被取消的事件是否最终得到纠正。

我已经离开 R 一段时间了,似乎无法弄清楚这一点。

【问题讨论】:

【参考方案1】:

更新答案

也许这会更好。我做了一个新的数据集,有以下情况:

    在 CAN/COMP 对之前有多个 CAN (visitid = 100) CAN/COMP 对之前的多个 COMP (visitid = 200) 没有 CAN 的 COMP (visitid = 300) 没有 COMP 的 CAN (visitid = 400)

我假设无论 CAN/COMP 对之前的 CAN 数量有多少,我们只会将其视为“更正”一次。因此,在这个数据集中,我们预计会有 2 次更正。

## read in data
text <- "visitid procedureid  collectiondatetime source status
100     100.644 2016-06-01 17:20:00      N    CAN
100     100.644 2016-12-03 17:20:00      N    CAN
100     100.644 2017-08-23 10:31:00      N    CAN
100     100.644 2017-08-25 15:48:00      N   COMP
200     100.644 2017-09-01 12:00:00     RS   COMP
200     100.644 2017-09-21 12:00:00     RS   COMP
200     100.644 2017-09-01 14:00:00     RS   COMP
200     100.644 2017-10-01 14:00:00     RS    CAN
200     100.644 2017-11-01 14:00:00     RS   COMP
300     100.644 2017-11-02 14:00:00     RS   COMP
400     100.644 2017-12-01 14:00:00     RS   CAN"
file <- textConnection(text, encoding = "UTF-8")
coln <- readLines(file, n = 1)
coln <- strsplit(coln, " ")[[1]]
coln <- coln[coln != ""]
on.exit(close(file))
df <- read.fwf(file = file, 
               widths = c(3, 12, 20, 7, 7),
               strip.white = TRUE,
               stringsAsFactors = FALSE)
colnames(df) <- coln
rm(coln, file, text)

然后我们可以将每个 CAN 与下一个状态相匹配。如果下一个状态(按日期/时间)是 COMP,则将其视为“已更正”。

library(tidyr)
library(dplyr)
test <- df %>%
        arrange(visitid, procedureid, source, collectiondatetime) %>%
        group_by(visitid, procedureid, source) %>%
        mutate(corrected = ifelse(status == "COMP", NA, 
                                 ifelse(lead(status) == "COMP", TRUE, NA))) %>%
        ungroup() %>%
        summarise(n = sum(corrected, na.rm = TRUE))
test


原答案

不确定这是否正是您想要的,但这里有一个选项。您可以为每次访问、程序和来源创建 CAN/COMP 对。然后你可以通过status 传播proceduredatetime,这样你就可以检查取消后程序完成的对。

library(dplyr)
library(tidyr)
test <- df %>%
    mutate(collectiondatetime = as.POSIXct(collectiondatetime)) %>%
    arrange(visitid, procedureid, source, collectiondatetime) %>%
    group_by(visitid, procedureid, source, status) %>%
    mutate(pair = row_number()) %>%
    spread(status, collectiondatetime) %>%
    ungroup() %>%
    mutate(corrected = CAN < COMP)
as.data.frame(test)

# output
  visitid procedureid source pair                 CAN                COMP corrected
1     100     100.644      N    1 2017-08-23 10:31:00 2017-08-25 15:48:00      TRUE
2     100     100.644     RS    1                <NA> 2017-09-01 12:00:00        NA
3     100     100.644     RS    2                <NA> 2017-09-21 12:00:00        NA
4     200     100.644      N    1                <NA> 2017-09-01 14:00:00        NA

然后您可以得到corrected 的总和以获取取消后程序执行的次数:

sum(test$corrected, na.rm = TRUE)

注意: 这假设对于给定的访问、过程和来源,从来没有一个 COMP 过程后跟一个 CAN,然后是一个 COMP。如果确实发生这种情况,您可以先删除在 CAN 程序之前执行的每次访问/程序/来源的 COMP 程序。

【讨论】:

谢谢!我的数据确实有 COMP,然后是 CAN。我将尝试删除 CAN 之前的 COMP。 @TomO 当然可以!如果您需要帮助,只需添加一个具有这种情况的示例数据集 这就是我所做的。我不确定这是否有意义。基本上使用了你的代码。然后。 group_by (visitid, procedureid, source) %>% mutate(recollect = ifelse(CAN % filter (!is.na(CAN)) %>% ungroup()%> % group_by(procedureid, source, recollect) %>% summarise(n=n()) @TomO 我认为这只有在 CAN/COMP 对之前只有一个 COMP 才有效 @TomO 我用一个新选项更新了我的答案。让我知道它是否适合你

以上是关于Dplyr条件逻辑计数行数的主要内容,如果未能解决你的问题,请参考以下文章

R语言dplyr包filter函数通过逻辑条件过滤数据实战

R(dplyr)中复位的条件运行计数(累计和)

如何根据过滤条件添加计数列而不是在dplyr中进行分组?

Verilog的非阻塞语句放到顺序块中,综合出来怎样的逻辑电路?

如果达到特定条件,计数重置为 0

oracle when 和 then怎么用!!!