I am working with the R programming language.
I have this dataset:
myt = structure(list(name = c("Alice", "Bob", "Bob", "Charlie", "Diana",
"Diana", "Eve", "Eve", "Frank", "Frank", "Frank", "Grace", "Grace",
"Henry", "Henry", "Henry"), country = c("USA", "Canada", "Mexico",
"UK", "France", "Germany", "USA", "Canada", "Mexico", "USA",
"UK", "France", "Germany", "USA", "Canada", "Mexico"), date_arrived = structure(c(17897,
18414, 18536, 18779, 18231, 18475, 18597, 18687, 18048, 18322,
18567, 17897, 18762, 18383, 18489, 18597), class = "Date"), date_left = structure(c(18322,
18506, 18659, 18840, 18444, 18567, 18659, 2932896, 18231, 18506,
2932896, 18353, 18809, 18489, 18597, 18748), class = "Date")), class = "data.frame", row.names = c(NA,
-16L))
I want to find out the following:
For every person that has data between May-1-2020 and May-1-2021
What percent of time did they spend in each country during this time period?
If they have data between this whole time period, I use 365 as a denominator. If they do not, I use the total number of days they have, i.e. max(365, total days)
I tried to do this in stages.
First, I identified the period:
period_start <- as.Date("2020-05-01")
period_end <- as.Date("2021-05-01")
total_period_days <- as.numeric(period_end - period_start)
Then, I made some columns to calculate statistics and filter on people who only have data during this time:
myt$effective_arrival <- pmax(myt$date_arrived, period_start)
myt$effective_departure <- pmin(myt$date_left, period_end)
myt$num_days_in_range <- ifelse(
myt$in_range == "yes",
as.numeric(myt$effective_departure - myt$effective_arrival),
0
)
myt_in_range <- myt[myt$in_range == "yes", ]
Then I did two aggregations:
days_by_country <- aggregate(
num_days_in_range ~ name + country,
data = myt_in_range,
FUN = sum
)
names(days_by_country)[3] <- "days_in_country"
person_totals <- aggregate(
days_in_country ~ name,
data = days_by_country,
FUN = sum
)
names(person_totals)[2] <- "total_days_present"
Finally, I did the merge and percent calculations:
person_totals$denominator <- pmin(person_totals$total_days_present, total_period_days)
final_results <- merge(days_by_country, person_totals, by = "name")
final_results$percentage <- round(
100 * final_results$days_in_country / final_results$denominator,
2
)
final_results <- final_results[order(final_results$name, final_results$country), ]
final_results <- final_results[, c("name", "country", "days_in_country",
"total_days_present", "denominator", "percentage")]
Is there some way I can do this all at once in R using dplyr?
Thanks!