问题描述
我希望有人可以帮助我解决我的问题,我知道使用两个for循环不是很有效,但这是我的第一个解决方案.我有一个数据框(AllPat),其中包含眼科患者(患者ID,日期和访问->'o'perations或'c'heckups)
I hope someone can help me with my problem, I know using two for-loops is not very efficient but that was my first solution. I have a data frame (AllPat) with eye-patients (patient-id, date and visit ->'o'perations or 'c'heckups)
#Pat Date Visit
#1,l 2015-03-30 c
#1,l 2015-06-03 o
#1,l 2015-07-01 o
#1,l 2015-07-20 c
#1,l 2016-03-16 o
#1,l 2016-04-13 o
#1,l 2016-05-09 c
#2,l 2014-12-23 c
#2,l 2015-01-21 o
#2,l 2015-03-16 c
#2,l 2015-11-23 o
我想计算每个患者ID的操作块数(检查前后)
And I want to count the operation-blocks for each patient-id (before and after a checkup)
#Pat Date Visit Block
#1,l 2015-03-30 c
#1,l 2015-06-03 o 1
#1,l 2015-07-01 o 2
#1,l 2015-07-20 c
#1,l 2016-03-16 o 1
#1,l 2016-04-13 o 2
#1,l 2016-05-09 c
#2,l 2014-12-23 c
#2,l 2015-01-21 o 1
#2,l 2015-03-16 c
#2,l 2015-11-23 o 1
这就是当前代码:
for(i in unique(AllPat$Pat)){
op <- 0
for(j in AllPat$Pat){
if(i == j) {
if(AllPat$Visit[AllPat$Pat == j] == "o") {
AllPat$Block[AllPat$Pat == j] <- op
op <- op+1
}
else op<-0
}
}
}
我的问题是,仅当我在数据框的视图中手动对它们进行排序时,$ Block中的值才可见,也许有人有更好的解决方案并可以帮助我
my problem is, that the values in $Block only get visible if I sort them by hand in the view of the data frame, maybe someone has a better solution and can help me
更新: 我当前的数据框,其中包含建议的功能rleid:
UPDATE:my current data frame with the suggested function rleid:
Patient Date Visit DiffDate Block
3,r 16.02.2016 m 0
3,r 16.02.2016 m 0 0
3,r 16.02.2016 m 0 0
3,r 16.02.2016 m 0 0
3,r 20.04.2016 o 64 1
3,r 18.05.2016 o 28 1 <<- should be 2
3,r 15.06.2016 o 28 1 <<- should be 3
3,r 04.07.2016 m 19 0
3,r 27.07.2016 o 23 1
3,r 24.08.2016 o 28 2
3,r 18.10.2016 o 55 3
也许我应该更改difftime函数?当前用于计数块的代码是:
maybe I should change my difftime function?The current code for counting the blocks is:
n <- nrow(AllPat)
AllPat<- transform(AllPat, Block = ave(1:n, rleid(Patient, Visit, (DiffDate<= 60)), FUN = seq_along) * (Visit== "o"))
和日期之间的差额:
setDT(AllPat)[, DiffDate:= difftime(AllPat$Date, shift(AllPat$Date), units = "days"), by = c("Patient")]
UPDATE
UPDATE
4,l 2015-05-18 m NA 0
4,l 2015-10-20 o 155 1
4,l 2016-05-31 o 224 2 <<-1
4,l 2016-07-26 o 56 1
data.table软件包中的
推荐答案
rleid
在这里可以提供帮助.我们将0用作检查块.
rleid
in the data.table package can help here. We have used 0 for the checkup blocks.
library(data.table)
AllPatDT <- data.table(AllPat)
AllPatDT[, Block := ave(.I, rleid(X.Pat, Visit), FUN = seq_along) * (Visit == "o")]
给予:
> AllPatDT
X.Pat Date Visit Block
1: #1,l 2015-03-30 c 0
2: #1,l 2015-06-03 o 1
3: #1,l 2015-07-01 o 2
4: #1,l 2015-07-20 c 0
5: #1,l 2016-03-16 o 1
6: #1,l 2016-04-13 o 2
7: #1,l 2016-05-09 c 0
8: #2,l 2014-12-23 c 0
9: #2,l 2015-01-21 o 1
10: #2,l 2015-03-16 c 0
11: #2,l 2015-11-23 o 1
如果您喜欢平直的data.frame,则仅使用data.table包中的rleid
,我们有:
If you prefer a straight data.frame then using only rleid
from the data.table package we have:
library(data.table)
n <- nrow(AllPat)
transform(AllPat, Block = ave(1:n, rleid(X.Pat, Visit), FUN = seq_along) * (Visit == "o"))
注意
我们将以下内容用作AllPat
:
Lines <- "#Pat Date Visit
#1,l 2015-03-30 c
#1,l 2015-06-03 o
#1,l 2015-07-01 o
#1,l 2015-07-20 c
#1,l 2016-03-16 o
#1,l 2016-04-13 o
#1,l 2016-05-09 c
#2,l 2014-12-23 c
#2,l 2015-01-21 o
#2,l 2015-03-16 c
#2,l 2015-11-23 o"
AllPat <- read.table(text = Lines, header = TRUE, comment.char = "", as.is = TRUE)
这篇关于通过ID列表进行循环计数值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!