问题
I want to generate the column: "PriorityCountInLast7Days". For a given employee A, this column counts the number of CASES in the last 7 days where PRIORITY is the same as the current case. How would I do that in R with the first 4 columns?
data <- data.frame(
Date = c("2018-06-01", "2018-06-03", "2018-06-03", "2018-06-03", "2018-06-04", "2018-06-01", "2018-06-02", "2018-06-03"),
Emp1 = c("A","A","A","A","A","A","B","B","B"),
Case = c("A1", "A2", "A3", "A4", "A5", "A6", "B1", "B2", "B3"),
Priority = c(0,0,0,1,2,0,0,0,0),
PriorityCountinLast7days = c(0,1,2,1,1,3,1,2,3))
+------------+------+------+----------+--------------------------+
| Date | Emp1 | Case | Priority | PriorityCountinLast7days |
+------------+------+------+----------+--------------------------+
| 2018-06-01 | A | A1 | 0 | 0 |
| 2018-06-03 | A | A2 | 0 | 1 |
| 2018-06-03 | A | A3 | 0 | 2 |
| 2018-06-03 | A | A4 | 1 | 1 |
| 2018-06-03 | A | A5 | 2 | 1 |
| 2018-06-04 | A | A6 | 0 | 3 |
| 2018-06-01 | B | B1 | 0 | 1 |
| 2018-06-02 | B | B2 | 0 | 2 |
| 2018-06-03 | B | B3 | 0 | 3 |
+------------+------+------+----------+--------------------------+
回答1:
You can accomplish this rolling window with an iterative conditional sum on your full dataset. What does this mean? Within a for loop you can check to see that your current date >= dates you want to include AND the dates you want to include >= to the date 7 days ago AND the cases you want to include are == to your current case. This logic combination in a loop will create this rolling filter for you. Here is a function:
rollPriority <- function(data, window = 7){
stopifnot(all(c("Date","Case","Priority") %in% colnames(data))) # string error check
data$Date <- as.Date(data$Date)
for(i in 1:nrow(data)){
#priorxdays <= dates we want <= current date
datecheck <- (data$Date[i] - (window-1)) <= data$Date & data$Date <= data$Date[i]
casecheck <- data$Case == data$Case[i]
data$PriorityCountinLastXdays[i] = sum(data$Priority[which(datecheck & casecheck)])
}
Xdays <- which(colnames(data) == "PriorityCountinLastXdays")
colnames(data)[Xdays] <- paste0("PriorityCountinLast", window, "days")
return(data)
}
In the future, please provide example data with a reproducible output. You will notice that we cannot match your expected 7 day rolling output having only seen 4 days of information. A quick method here is to use expand.grid()
to generate combinations, and set.seed()
to preserve sampling output:
# Reproducible Example Data
dat <- expand.grid(Date = seq.Date(as.Date("2018-06-01"),
as.Date("2018-06-4"),
by = "day"),
Case = as.factor(sort(apply(expand.grid(c("A","B"),1:2),
1,
paste0,
collapse = ""))))
# Ensures random sampling is identical each time
set.seed(42);
dat$Priority <- sample(0:1, nrow(dat), replace = T)
# The function
rollPriority(dat, 2)
# Date Case Priority PriorityCountinLast2days
#1 2018-06-01 A1 1 1
#2 2018-06-02 A1 1 2
#3 2018-06-03 A1 0 1
#4 2018-06-04 A1 1 1
#5 2018-06-01 A2 1 1
#6 2018-06-02 A2 1 2
#7 2018-06-03 A2 1 2
#8 2018-06-04 A2 0 1
#9 2018-06-01 B1 1 1
#10 2018-06-02 B1 1 2
#11 2018-06-03 B1 0 1
#12 2018-06-04 B1 1 1
#13 2018-06-01 B2 1 1
#14 2018-06-02 B2 0 1
#15 2018-06-03 B2 0 0
#16 2018-06-04 B2 1 1
This way it is easier for someone to accurately assist you.
来源:https://stackoverflow.com/questions/52023433/count-number-of-times-a-factor-appears-during-rolling-window