user2716568
user2716568

Reputation: 1946

How to create a new column, by variable?

My data includes data on different people (ID) over each Day of the week and the time they spend in different areas of the hospital or Ward. I am given this time, in minutes:seconds or Duration. An example of my data is:

ShiftData <- data.frame(ID = c("Nelson", "Nelson", "Nelson", "Nelson", "Nelson", 
                      "Justin", "Justin", "Justin", "Justin", "Justin", 
                      "Nelson", "Nelson", "Nelson", "Nelson", "Nelson", 
                      "Justin", "Justin", "Justin", "Justin", "Justin"), 
               Day = c("Monday", "Monday", "Monday", "Monday", "Monday", 
                       "Monday", "Monday", "Monday", "Monday", "Monday",
                      "Tuesday", "Tuesday", "Tuesday", "Tuesday", "Tuesday", 
                      "Tuesday", "Tuesday", "Tuesday", "Tuesday", "Tuesday"), 
               Ward = c("Gen", "Anaesth", "Front Desk", "PreOp", "Front Desk", 
                       "PreOp", "Front Desk", "Anaesth", "Front Desk", "Gen",
                       "Gen", "Anaesth", "PreOp", "Front Desk", "Gen", 
                       "Front Desk", "PreOp", "PostOp", "Front Desk", "Anaesth"),
               Duration = c("5:35", "4:08", "4:30", "6:33", "4:17", 
                            "15:35", "4:28", "9:37", "18:33", "4:20",
                            "9:45", "8:28", "6:37", "2:34", "4:27", 
                            "19:35", "4:20", "9:47", "11:33", "4:26"))

I first wish to include a column that indicates when each ID was on a rotation or shift. A "Front Desk" in the Ward column indicates when a person alters their shift. A person may start on "Front Desk", regulated by how many hours they work the day before (this calculation not required for the current analysis). My anticipated output would be:

ShiftData$Shift <- c(1,1,0,2,0,
                     1,0,2,0,3,
                     1,1,1,0,2,
                     0,1,1,0,2)

My question is similar to this question except when there is a "Front Desk" I want a 0 and any activity afterward, to count sequentially up.

How do I please create this?

I know that I can include a 0 for "Front Desk" using:

ShiftData$Shift <- ifelse(ShiftData$Ward=='Front Desk', 0, NA)

But I am unsure how to include a sequential count for every other part of the column?

Upvotes: 4

Views: 249

Answers (2)

Scarabee
Scarabee

Reputation: 5704

Note that your question is quite similar to this one.

So this is a way to solve it:

library(dplyr)

ShiftData %>%
  group_by(ID, Day) %>% 
  mutate(Shift = cumsum(Ward != "Front Desk" & lag(Ward) %in% c("Front Desk", NA))) %>% 
  mutate(Shift = ifelse(Ward == "Front Desk", 0, Shift))

# Source: local data frame [20 x 5]
# Groups: ID, Day [4]
# 
#        ID     Day       Ward Duration Shift
#    <fctr>  <fctr>     <fctr>   <fctr> <dbl>
# 1  Nelson  Monday        Gen     5:35     1
# 2  Nelson  Monday    Anaesth     4:08     1
# 3  Nelson  Monday Front Desk     4:30     0
# 4  Nelson  Monday      PreOp     6:33     2
# 5  Nelson  Monday Front Desk     4:17     0
# 6  Justin  Monday      PreOp    15:35     1
# 7  Justin  Monday Front Desk     4:28     0
# 8  Justin  Monday    Anaesth     9:37     2
# 9  Justin  Monday Front Desk    18:33     0
# 10 Justin  Monday        Gen     4:20     3
# 11 Nelson Tuesday        Gen     9:45     1
# 12 Nelson Tuesday    Anaesth     8:28     1
# 13 Nelson Tuesday      PreOp     6:37     1
# 14 Nelson Tuesday Front Desk     2:34     0
# 15 Nelson Tuesday        Gen     4:27     2
# 16 Justin Tuesday Front Desk    19:35     0
# 17 Justin Tuesday      PreOp     4:20     1
# 18 Justin Tuesday     PostOp     9:47     1
# 19 Justin Tuesday Front Desk    11:33     0
# 20 Justin Tuesday    Anaesth     4:26     2

How it works: After grouping, we create the Shift column by adding 1 each time a non-Front Desk is preceded by a Front Desk. Then we replace Shift by 0 on all Front Desk rows.

Upvotes: 2

Pdubbs
Pdubbs

Reputation: 1987

This problem can be solved with dplyr:

ShiftData$Shift <- (ShiftData %>%
                    group_by(ID,Day) %>%
                    mutate(tmp = ifelse(Ward=="Front Desk",1,0), #tag to sum front desk shifts
                           tmp2 = cumsum(tmp),                   #cumsum shows shifts in a day
                           Ward1 = Ward[1],                      #this and the below count your first shift if you didn't start on desk duty
                           shift = ifelse(Ward1=="Front Desk",tmp2,tmp2+1))
                    )$shift
ShiftData$Shift[ShiftData$Ward=="Front Desk"] <- 0

Upvotes: 2

Related Questions