Reputation: 15
I have a dataset like this
PT <- c(1,1,1,1,2,2,2,3,3,3,3,3)
visit <- c("w1","w2","w3","w4","w1","w2","w3","w1","w2","w3","w4","w5")
dose_level <- c("250", "250", "200", "200", "250", "250", "250", "200","200","150", "150", "100")
test <- data.frame(PT, visit, dose_level)
What I want to do is to calculate the number of times dose-level reduction by each patient. The result would be like:
Thank you in advance. I appreciate all your help.
Upvotes: 0
Views: 49
Reputation: 138
test <- data.table(test)
test[,dose_level:=as.numeric(as.character(dose_level))]
test[,lag:=shift(dose_level,1),by="PT"]
#calculate difference between actual and lag
test[,diff:=dose_level-lag]
#flag to check if the diff is +ve or -ve
test[,check:=ifelse(diff<0,1,0)]
test_summarise <- test[,.(sum(check,na.rm=T)),by="PT"]
test_summarise
PT V1
1 1
2 0
3 2
Upvotes: 0
Reputation: 5788
Base R one (obfuscated) liner:
data.frame(PT = unique(PT),
times = sapply(split(test, test$PT), function(x){sum(c(FALSE, abs(diff(as.numeric(x$dose_level))) > 0))}))
Upvotes: 0
Reputation: 76402
In base R this can be done with aggregate
.
aggregate(dose_level ~ PT, test, function(x){
y <- as.integer(as.character(x))
sum(diff(y) < 0)
})
# PT dose_level
#1 1 1
#2 2 0
#3 3 2
Upvotes: 3
Reputation: 1688
I guess patient 3 should be 2?
PT <- c(1,1,1,1,2,2,2,3,3,3,3,3)
visit <- c("w1","w2","w3","w4","w1","w2","w3","w1","w2","w3","w4","w5")
dose_level <- c("250", "250", "200", "200", "250", "250", "250", "200","200","150", "150", "100")
test <- data.frame(PT,visit, dose_level)
library(data.table)
setDT(test)[,.(times=sum(dose_level<shift(dose_level),na.rm = TRUE)),by=.(PT)]
#> PT times
#> 1: 1 1
#> 2: 2 0
#> 3: 3 2
Upvotes: 2