我可以根据许多相关条件在R中筛选(或创建新的)数据集吗



我已经很久没有在R中操作数据集了,到目前为止,我一直在excel中手动操作,但这很麻烦,因为我的数据集不小!

我对以下变量感兴趣:

PATIENT_ID-在数据集中多次出现

CYCLE_ID-唯一

CYCLE_NO-按时间顺序从每个PATIENT_ID 1开始

CALC_ACT-是或否

我需要的是创建一个符合以下标准的新数据集:对于单个PATIENT_ ID;是";和其中CALC_ ACT=="1"的一行;否";。

CALC_ ACT==";是";行必须具有比CALC_ ACT==;否";一行

我只需要每个PATIENT_ID匹配一个,忽略其余的。

对于一个已经多年没有做任何编程的人来说,这件事的复杂性让我头疼!!!

提前感谢

在下面的例子中,应该只保留第3行和第4行。第4行(CYCLE_NO==6(是CALC_ACT第一次为"是",上一个循环为"否"。PATIENT_ID 222和456的行不符合标准,因为它们需要同时具有CALC_ACT的"是"one_answers"否"二者。希望这是有意义的。。。

PatientData <- data.frame(PATIENT_ID = c(123, 123, 123, 123, 123, 222, 222, 222, 456, 456), CYCLE_ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), CYCLE_NO = c(1, 3, 4, 6, 7, 2, 3, 4, 1, 2), CALC_ACT = c("Yes", "No", "No", "Yes", "Yes", "No", "No", "No", "Yes", "Yes"))
PatientData
PATIENT_ID CYCLE_ID CYCLE_NO CALC_ACT
1         123        1        1      Yes
2         123        2        3       No
3         123        3        4       No
4         123        4        6      Yes
5         123        5        7      Yes
6         222        6        2       No
7         222        7        3       No
8         222        8        4       No
9         456        9        1      Yes
10        456       10        2      Yes

这里有一个函数,它应该按照逻辑工作。

return_rows <- function(CALC_ACT, CYCLE_NO) {
#indices of 'yes' rows
yes_ind <- which(CALC_ACT == 'Yes') 
#indices of 'no' rows
no_ind <- which(CALC_ACT == 'No')
#Only if both the yes and no rows are present else don't select any row
if(length(yes_ind) && length(no_ind)) {
#Get the minimum length of yes and no rows
n <- min(length(yes_ind), length(no_ind))
#Get the first value where yes no has higher CYCLE_NO than the no row
ind <- which(CYCLE_NO[yes_ind[1:n]] > CYCLE_NO[no_ind[1:n]])[1]
#Return the corresponding index
sort(c(yes_ind[ind], no_ind[ind]))
} else 0
}

将此功能应用于每个PATIENT_ID-

PatientData %>%
arrange(PATIENT_ID, CYCLE_NO) %>%
group_by(PATIENT_ID) %>%
slice(return_rows(CALC_ACT, CYCLE_NO)) %>%
ungroup
#  PATIENT_ID CYCLE_ID CYCLE_NO CALC_ACT
#       <dbl>    <dbl>    <dbl> <chr>   
#1        123        3        4 No      
#2        123        4        6 Yes     

此代码应能在中工作

library(data.table)
PatientData <- data.frame(PATIENT_ID = c(123, 123, 123, 123, 123, 222, 222, 222, 456, 456), CYCLE_ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
CYCLE_NO = c(1, 3, 4, 6, 7, 2, 3, 4, 1, 2), CALC_ACT = c("Yes", "No", "No", "Yes", "Yes", "No", "No", "No", "Yes", "Yes"))
d1 = data.table(PatientData[order(PatientData$PATIENT_ID, PatientData$CYCLE_NO),])
d1$CALC_ACT1 = ifelse(d1$CALC_ACT == 'Yes',1,0)
d1[ , diff := CALC_ACT1 - shift(CALC_ACT1), by = PATIENT_ID]   
out = d1[c(which(d1$diff == 1), (which(d1$diff == 1) -1)),]
out

最新更新