我有一個像這樣的資料集 PosNeg。我需要找到具有像這樣的模式的 ID 計數 - PNPP 或 NPNNPN - 在兩個 P(正)之間至少有一個 N(負)。如果此模式至少出現一次,則計算該 ID。日期始終按升序排列。
例如:對于 ID 1,我在 02/25 的兩個 P 之間至少有 1 N,因此我將計算 ID 1。ID 2 和 3 在 2 P 之間沒有 N,因此不計算在內。ID 4 在 03/18 的兩個 P 之間也有一個 N,因此我將包括 4。因此滿足條件的 ID 總數為 2(1 和 4)
我的想法是找到每個 ID 的正數的 min(date) 和正數的 max(date),并在這些日期之間查找任何負數,但不知道如何實作它。R/Python/SQL 中的任何建議都會有所幫助。
| ID | 測驗 | 日期 |
|---|---|---|
| 1 | 磷 | 2021-01-02 |
| 1 | 磷 | 2021-01-08 |
| 1 | ? | 2021-02-25 |
| 1 | 磷 | 2021-03-26 |
| 2 | ? | 2021-02-05 |
| 2 | 磷 | 2021-03-04 |
| 2 | ? | 2021-03-30 |
| 3 | ? | 2021-01-24 |
| 3 | 磷 | 2021-02-10 |
| 4 | ? | 2021-02-15 |
| 4 | 磷 | 2021-02-28 |
| 4 | ? | 2021-03-18 |
| 4 | 磷 | 2021-04-11 |
輸出:
| 全部的 |
|---|
| 2 |
EDIT1:兩個P之間可能有多個N(至少1個),而不僅僅是1,我想將它包括在我的計數中。
EDIT2:我希望包含此 ID,但它不包含在結果資料框中。但是,在 2 個 P 之間有多個 N。
| ID | 日期 | 測驗 |
|---|---|---|
| 1 | 2020-06-12 | ? |
| 1 | 2020-08-20 | ? |
| 1 | 2020-10-04 | ? |
| 1 | 2020-12-09 | ? |
| 1 | 2021-01-08 | 磷 |
| 1 | 2021-02-05 | 磷 |
| 1 | 2021-03-26 | 磷 |
| 1 | 2021-05-26 | 磷 |
| 1 | 2021-06-30 | ? |
| 1 | 2021-07-21 | ? |
| 1 | 2021-08-23 | ? |
| 1 | 2021-09-16 | ? |
| 1 | 2021-10-08 | ? |
| 1 | 2021-10-18 | ? |
| 1 | 2021-10-29 | 磷 |
EDIT3:上一個編輯中的 ID 是1而我的真實資料的輸出從15開始。我認為它應該從 1 開始。另外,它在我的真實資料中不是 N 和 P,而是“負”和“正”。我的代碼現在是這樣的:
data4c %>% group_by(STUDY_ID)
%>% summarise(isP = str_detect(str_c(TEST, collapse = ""),
"PositiveNegative Positive"), .groups = 'drop')
%>% filter(isP)

uj5u.com熱心網友回復:
這是一個選項str_c/str_detect- 按“ID”分組,paste“測驗”元素,然后檢查模式是否P后跟一個或多個N(N ),然后P出現
library(stringr)
library(dplyr)
df1 %>%
group_by(ID) %>%
summarise(isP = str_detect(str_c(substr(Test,1, 1) collapse = ""), "PN P"),
.groups = 'drop') %>%
filter(isP)
# A tibble: 2 × 2
ID isP
<int> <lgl>
1 1 TRUE
2 4 TRUE
使用 OP 的新資料
> df2 %>% group_by(ID) %>%
summarise(isP = str_detect(str_c(substr(TEST,1, 1), collapse = ""), "PN P"),
.groups = 'drop') %>%
filter(isP)
# A tibble: 1 × 2
ID isP
<int> <lgl>
1 1 TRUE
編輯:添加substr以提取“測驗”列中的第一個字母,因為原始資料值不是“P”或“N”,如示例所示
資料
df2 <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L), DATE = c("2020-06-12", "2020-08-20", "2020-10-04",
"2020-12-09", "2021-01-08", "2021-02-05", "2021-03-26", "2021-05-26",
"2021-06-30", "2021-07-21", "2021-08-23", "2021-09-16", "2021-10-08",
"2021-10-18", "2021-10-29"), TEST = c("N", "N", "N", "N", "P",
"P", "P", "P", "N", "N", "N", "N", "N", "N", "P")),
class = "data.frame", row.names = c(NA,
-15L))
uj5u.com熱心網友回復:
更新的答案
library(dplyr)
dat %>%
group_by(ID) %>%
summarize(
yourcond = grepl(pattern = "PN P", x = paste(Test, collapse = "")))
結果:
# A tibble: 5 x 2
ID yourcond
<dbl> <lgl>
1 1 TRUE
2 2 FALSE
3 3 FALSE
4 4 TRUE
5 5 TRUE
新資料:
dat <- structure(list(ID = c(1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5), Test = c("P", "P",
"N", "P", "N", "P", "N", "N", "P", "N", "P", "N", "P", "N", "N",
"N", "N", "P", "P", "P", "P", "N", "N", "N", "N", "N", "N", "P"
), Date = c("2021-01-02", "2021-01-08", "2021-02-25", "2021-03-26",
"2021-02-05", "2021-03-04", "2021-03-30", "2021-01-24", "2021-02-10",
"2021-02-15", "2021-02-28", "2021-03-18", "2021-04-11", "2020-06-12",
"2020-08-20", "2020-10-04", "2020-12-09", "2021-01-08", "2021-02-05",
"2021-03-26", "2021-05-26", "2021-06-30", "2021-07-21", "2021-08-23",
"2021-09-16", "2021-10-08", "2021-10-18", "2021-10-29")), row.names = c(NA,
-28L), class = "data.frame")
上一個答案
library(dplyr)
dat %>%
group_by(ID) %>%
summarize(
yourcond = any((Test == "N") & (lag(Test) == "P") & (lead(Test) == "P")))
結果:
# A tibble: 4 x 2
ID yourcond
<int> <lgl>
1 1 TRUE
2 2 NA
3 3 NA
4 4 TRUE
您可以添加count(yourcond)到 dplyr 鏈以回傳每個 NA 和 TRUE 的計數。
資料:
dat <- structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 4L,
4L, 4L, 4L), Test = c("P", "P", "N", "P", "N", "P", "N", "N",
"P", "N", "P", "N", "P"), Date = c("2021-01-02", "2021-01-08",
"2021-02-25", "2021-03-26", "2021-02-05", "2021-03-04", "2021-03-30",
"2021-01-24", "2021-02-10", "2021-02-15", "2021-02-28", "2021-03-18",
"2021-04-11")), class = "data.frame", row.names = c(NA, -13L))
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/478503.html
