R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.

When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

#install.packages("jsonlite")
#install.packages("lubridate")
#install.packages("dyplr")
#install.packages("readxl")
#install.packages("revgeo")
#install.packages("psych")
library(psych)
## Warning: package 'psych' was built under R version 4.4.1
library(revgeo)
## Warning: package 'revgeo' was built under R version 4.4.1
library(readxl)
## Warning: package 'readxl' was built under R version 4.4.1
library(lubridate)
## Warning: package 'lubridate' was built under R version 4.4.1
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(jsonlite)
## Warning: package 'jsonlite' was built under R version 4.4.1
# Audio started: When a user begins playing a meditation.
# Audio completed: When a user finishes listening to a meditation.
# Track completed: Triggered either when a user completes a meditation or swipes on a track in a pack. They can also remove a track from the list by swiping again (this #  action doesn’t impact the “audio completed” status).
# Track rated: Optional rating after a meditation. Users can only rate after listening to a meditation, but they are not required to rate it.
# User stats: Automatically calculated totals per user, which they can also manually edit.

# data = tracks completed
# na_data = users who have not started any meditations
# app_loaded = app opens
# user_stats
opens <- fromJSON("C:/Users/juadams/Documents/Needed Docs/Research (Apps)/Medito_data/app-loaded.json")
stats <- fromJSON("C:/Users/juadams/Documents/Needed Docs/Research (Apps)/Medito_data/output/users-stats.json")
write.csv(stats, "users-stats.csv")
tracks <- fromJSON("C:/Users/juadams/Documents/Needed Docs/Research (Apps)/Medito_data/output/audio-completed.json")
write.csv(tracks, "audio-completed.csv")
#opens <- fromJSON("C:/Users/juadams/Documents/Needed Docs/Research (Apps)/Medito_data/tracks-completed-fresh-11092024.json")
na_opens <- readLines("C:/Users/juadams/Documents/Needed Docs/Research (Apps)/Medito_data/output/na-app-loaded.txt")
## Warning in readLines("C:/Users/juadams/Documents/Needed Docs/Research
## (Apps)/Medito_data/output/na-app-loaded.txt"): incomplete final line found on
## 'C:/Users/juadams/Documents/Needed Docs/Research
## (Apps)/Medito_data/output/na-app-loaded.txt'
#write.csv(na_opens, "na-app-loaded.csv")
tracks_started <- fromJSON("C:/Users/juadams/Documents/Needed Docs/Research (Apps)/Medito_data/output/audio-started.json")

# NOTE: Remove those with no opens? 
# NOTE: Change NAs to 0? Currently when no tracks completed, the user will get NA for file_duration. Currently this IS being done at like 249.
# Load the engagement user data
#data <- read.csv("C:/Users/juadams/Documents/Research (Apps)/Medito_output_20072024/output/tracks_completed_14082024.csv")
#opens <- read.csv("C:/Users/juadams/Documents/Research (Apps)/Medito_data/output/app-loaded.csv")
#stats <- read.csv("C:/Users/juadams/Documents/Research (Apps)/Medito_data/output/app-loaded.csv")

# Load the qualtrics user data
results <- read.csv("C:/Users/juadams/Documents/Needed Docs/Research (Apps)/Medito_data/Medito Engagement - Baseline_September 16, 2024_00.47.csv")

# Convert to data frame for analysis
tracks <- as.data.frame(tracks)

# Save the data frame to a CSV file
#write.csv(df, file = "C:/Users/juadams/Documents/Research #(Apps)/Medito_output_20072024/output/tracks_completed_14082024.csv", row.names = FALSE)
# Load the CSV file with the ID replacements
file_path <- "C:/Users/juadams/Documents/Needed Docs/Research (Apps)/Medito_data/invalid_ids_06092024.csv"
id_replacements <- read.csv(file_path)

#NOTE: Should the invalid ID replacement be done AFTER the merge? I think at this stage means that the data gets merged better i.e. right ID from medito matched.
# Replace missing Medito_ID values with Q_Medito_ID values
results <- results %>%
  mutate(Medito_ID = ifelse(is.na(Medito_ID), Q_Medito_ID, Medito_ID))

# Remove rows with empty Medito_ID
#results <- results %>%
#  filter(Medito_ID != "")

# Check for duplicate Medito_IDs
duplicate_ids <- results %>%
  filter(!is.na(Medito_ID) & Medito_ID != "") %>%  # Exclude NAs and empty strings
  group_by(Medito_ID) %>%
  filter(n() > 1) %>%
  ungroup()
library(dplyr)
library(dplyr)
library(dplyr)

# Step 1: Count non-NA values for each row and add it as a new column
results <- results %>%
  mutate(non_na_count = rowSums(!is.na(across(everything()))))

# Step 2: For each Medito_ID, keep the row with the maximum non-NA count
results_cleaned <- results %>%
  group_by(Medito_ID) %>%
  filter(non_na_count == max(non_na_count)) %>%
  ungroup() %>%
  # Step 3: Remove any exact duplicates (where all values are the same)
  distinct()

# Display the number of rows removed
cat("Duplicates handled and cleaned. Number of rows removed:", nrow(results) - nrow(results_cleaned), "\n")
## Duplicates handled and cleaned. Number of rows removed: 0
# Initialize vectors to store valid and invalid IDs
valid_ids <- c()
invalid_ids <- c()
#REad the CSV file containing columns A (old IDs) and B (new IDs)
id_replacements <- read.csv(file_path)

# Use a left join to replace any matching IDs in results$Medito_ID with those in column B
results <- results %>%
  left_join(id_replacements, by = c("Medito_ID" = "A")) %>%
  mutate(ID_replaced = ifelse(!is.na(B) & Medito_ID != B, TRUE, FALSE),
         Medito_ID = ifelse(!is.na(B), B, Medito_ID)) 
## Warning in left_join(., id_replacements, by = c(Medito_ID = "A")): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 753 of `x` matches multiple rows in `y`.
## ℹ Row 25 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
##   "many-to-many"` to silence this warning.
 # select(-B) # Remove the column B after replacement

# Print the IDs that were replaced and their new values
replaced_ids <- results %>%
  filter(ID_replaced == TRUE) %>%
  select(Old_ID = Medito_ID, New_ID = B)

# Print the list of replaced IDs
print(replaced_ids)
##                                  Old_ID                               New_ID
## 1  163d2956-17d2-4d6d-a337-03c7a22a394a 163d2956-17d2-4d6d-a337-03c7a22a394a
## 2  6abe7576-5d47-4f17-81e3-644728584cbb 6abe7576-5d47-4f17-81e3-644728584cbb
## 3  39bb6f30-31bd-466b-9ab3-1285815aeba8 39bb6f30-31bd-466b-9ab3-1285815aeba8
## 4  6b935c96-bd4b-4095-8e85-93efa73dd0bb 6b935c96-bd4b-4095-8e85-93efa73dd0bb
## 5      client_clyxqq4n7000000i8v0452o4z     client_clyxqq4n7000000i8v0452o4z
## 6  1cc30a0f-fa06-4f59-a83e-41cc59763a0c 1cc30a0f-fa06-4f59-a83e-41cc59763a0c
## 7  a120bfde-49d6-4221-b18a-99900064c398 a120bfde-49d6-4221-b18a-99900064c398
## 8      client_clyz6c3d1000000i8dw2ubivf     client_clyz6c3d1000000i8dw2ubivf
## 9      client_clyzi8qfo000000i87sqmlwe4     client_clyzi8qfo000000i87sqmlwe4
## 10     client_clz250871000000i8hbl26ygx     client_clz250871000000i8hbl26ygx
## 11 942c07c8-2a6d-48a8-8950-748afd47e0cb 942c07c8-2a6d-48a8-8950-748afd47e0cb
## 12 4097f545-a285-4ad9-b73e-583aadf90698 4097f545-a285-4ad9-b73e-583aadf90698
## 13     client_cm01ex817000000i8qsc30h2s     client_cm01ex817000000i8qsc30h2s
## 14     client_cm018a0gs000000i8pqogkeri     client_cm018a0gs000000i8pqogkeri
## 15     client_cm01tpuj7000000i8zel2w8kk     client_cm01tpuj7000000i8zel2w8kk
## 16     client_cm0297w1p000000i82hkprfhj     client_cm0297w1p000000i82hkprfhj
## 17     client_cm021g621000000i86kjor68f     client_cm021g621000000i86kjor68f
## 18     client_cm021g621000000i86kjor68f     client_cm021g621000000i86kjor68f
## 19     client_cm029sq5z000000i8lmixi80k     client_cm029sq5z000000i8lmixi80k
## 20     client_cm02phv4p000000i8cldte9jb     client_cm02phv4p000000i8cldte9jb
## 21         client_37zzc000000i8v3mi3ce3         client_37zzc000000i8v3mi3ce3
## 22     client_cm02tguuk000000i8if0ky82v     client_cm02tguuk000000i8if0ky82v
## 23     client_cm02h9p50000000i8qjcxbf6r     client_cm02h9p50000000i8qjcxbf6r
## 24                             Graham58                             Graham58
## 25     client_cm032027z000000i8rtedpyqh     client_cm032027z000000i8rtedpyqh
## 26     client_cm021g621000000i86kjor68f     client_cm021g621000000i86kjor68f
## 27     client_cm021g621000000i86kjor68f     client_cm021g621000000i86kjor68f
## 28     client_cm034lyji000000i834w0tr1f     client_cm034lyji000000i834w0tr1f
## 29     client_cm03jb45w000000i8jyemrgex     client_cm03jb45w000000i8jyemrgex
## 30     client_cm03u372n000000i87x8ndwtt     client_cm03u372n000000i87x8ndwtt
## 31     client_cm03w1p03000000i87jlv9l0u     client_cm03w1p03000000i87jlv9l0u
## 32     client_cm03sxyyh000000i8mo0646d4     client_cm03sxyyh000000i8mo0646d4
## 33     client_cm04a9nvv000000i8urb7c75f     client_cm04a9nvv000000i8urb7c75f
## 34     client_cm04lxjnb000000i8isc1mart     client_cm04lxjnb000000i8isc1mart
## 35       client_05d971r000000i8b9dn30ow       client_05d971r000000i8b9dn30ow
## 36     client_cm04rtyvs000000i8wlihcu7v     client_cm04rtyvs000000i8wlihcu7v
## 37     client_cm05jimro000000i8w0v8a5ql     client_cm05jimro000000i8w0v8a5ql
## 38     client_cm06hakyd000000i85z4ivumx     client_cm06hakyd000000i85z4ivumx
## 39     client_cm06igj74000000i8eukt751p     client_cm06igj74000000i8eukt751p
## 40       client_06v04nj000000i83a0x9vdv       client_06v04nj000000i83a0x9vdv
## 41     client_cm076abrh000000i8zva9nnwj     client_cm076abrh000000i8zva9nnwj
## 42     client_cm07g3rg3000000i8h4ck6ivc     client_cm07g3rg3000000i8h4ck6ivc
## 43     client_cm07lou2x000000i8ul0s6kat     client_cm07lou2x000000i8ul0s6kat
## 44     client_cm05okxu6000000i8rmdtbqew     client_cm05okxu6000000i8rmdtbqew
## 45     client_cm07q2tss000000i8qf85awsd     client_cm07q2tss000000i8qf85awsd
## 46     client_cm0827pil000000i8vd5szh57     client_cm0827pil000000i8vd5szh57
## 47     client_cm0881cm6000000i8p2jjf92j     client_cm0881cm6000000i8p2jjf92j
## 48     client_cm088hxi6000000i8vvfoo54e     client_cm088hxi6000000i8vvfoo54e
## 49 client_client_cm081ir0m000000i8u5ilx client_client_cm081ir0m000000i8u5ilx
# Print the quantity of replacements
cat("Number of IDs replaced: ", nrow(replaced_ids), "\n")
## Number of IDs replaced:  49
# Clean up the results dataframe by removing temporary columns
results <- results %>%
  select(-B, -ID_replaced)


# Save the invalid IDs to a CSV file
#write.csv(invalid_ids, "C:/Users/juadams/Documents/Research (Apps)/Medito_data/invalid_ids_new_06092024.csv", row.names = FALSE)
# Cutoff non-new users

# Define the cutoff date
cutoff_date <- 1710844800
cutoff_date <- cutoff_date * 1000

# Identify users who have opens before the cutoff date
users_before_cutoff <- opens %>%
  filter(created < cutoff_date) %>%
  distinct(user_id)

# Number of users with events before the cutoff
num_users_before_cutoff <- nrow(users_before_cutoff)
cat("Number of users with events before the cutoff date:", num_users_before_cutoff, "\n")
## Number of users with events before the cutoff date: 0
# Print the earliest 'created' timepoint and number of users with events before cutoff
earliest_created_time <- min(opens$created, na.rm = TRUE)
cat("Earliest 'created' timepoint in the dataset:", earliest_created_time, "\n")
## Earliest 'created' timepoint in the dataset: 1.721251e+12
# Identify users who have TRACKs before the cutoff date
users_before_cutoff_tracks <- tracks %>%
  filter(created < cutoff_date) %>%
  distinct(user_id)

# Number of users with events before the cutoff
num_users_before_cutoff <- nrow(users_before_cutoff_tracks)
cat("Number of users with tracks before the cutoff date:", num_users_before_cutoff, "\n")
## Number of users with tracks before the cutoff date: 175
# Print the earliest 'created' timepoint and number of users with events before cutoff
earliest_created_time <- min(tracks$created, na.rm = TRUE)
cat("Earliest 'created' timepoint in the tracks dataset:", earliest_created_time, "\n")
## Earliest 'created' timepoint in the tracks dataset: 1.697432e+12
# For opens
if (!inherits(opens$created, "POSIXct")) {
  opens <- opens %>%
    mutate(created_date = as.POSIXct(created / 1000, origin = "1970-01-01", tz = "UTC"))
}

# For tracks
if (!inherits(tracks$created, "POSIXct")) {
  tracks <- tracks %>%
    mutate(created_date = as.POSIXct(created / 1000, origin = "1970-01-01", tz = "UTC"))
}

# For tracks
if (!inherits(tracks_started$created, "POSIXct")) {
  tracks <- tracks %>%
    mutate(created_date = as.POSIXct(created / 1000, origin = "1970-01-01", tz = "UTC"))
}

# Adjust device times to the right format
#opens <- opens %>%
#  mutate(device_time = as.POSIXct(device_time, format = "%Y-%m-%d %H:%M:%S"))

# Get the earliest device time for each user
earliest_opens <- opens %>%
  group_by(user_id) %>%
  summarize(earliest_device_time = min(created), .groups = 'drop')

# Join earliest_opens with tracks to include all users, regardless of whether they have tracks
tracks_with_earliest <- earliest_opens %>%
  left_join(tracks, by = "user_id")

filtered_tracks_30 <- tracks_with_earliest %>%
  filter(is.na(created) | (created >= earliest_device_time & created <= (earliest_device_time + 30*24*60*60)))

filtered_tracks <- filtered_tracks_30 %>%
  filter(!user_id %in% users_before_cutoff$user_id)

#NOTE: This doesn't remove anything from results?
filtered_results <- results %>%
  filter(!Medito_ID %in% users_before_cutoff_tracks$user_id)

results <- filtered_results

# Remaining after filtering non-new in filtered_tracks: 899 obs. 175 non-new users completed survey. 
# Load necessary libraries
library(dplyr)
library(lubridate)

# Convert milliseconds to seconds and then to POSIXct
earliest_opens <- earliest_opens %>%
  mutate(
    earliest_device_time = as.numeric(earliest_device_time) / 1000,  # Convert milliseconds to seconds
    earliest_device_time = as.POSIXct(earliest_device_time, origin = "1970-01-01", tz = "UTC")  # Convert to POSIXct
  )

print(earliest_opens)
## # A tibble: 1,014 × 2
##    user_id                              earliest_device_time
##    <chr>                                <dttm>              
##  1 0054cc73-ba11-462c-a6e0-782048467d54 2024-07-21 04:01:38 
##  2 005d02a2-fde1-4e0c-9aa8-0249c4e39a30 2024-08-19 16:24:11 
##  3 00d0aaf2-4af1-4ca9-a213-937aff38a891 2024-07-19 06:35:11 
##  4 0150ef07-6c5f-4471-a6e8-93e24a74e103 2024-07-27 04:03:14 
##  5 01a42e4a-8d1a-4e4c-9d6b-c35fb085a129 2024-07-19 21:19:36 
##  6 03028622-04e6-48b9-ae73-33c4b0ae5b2f 2024-07-24 08:48:44 
##  7 040d054f-4eac-4515-855f-471820fd91d4 2024-07-29 20:38:54 
##  8 041c8035-89b4-4e0f-89fe-5f54bc446f1f 2024-07-26 08:51:58 
##  9 05db88aa-9b22-40f9-afe5-589904de7efc 2024-07-22 04:17:31 
## 10 07cc87e7-74c3-4173-823e-1c9f77aff706 2024-07-18 02:56:03 
## # ℹ 1,004 more rows
# Merge tracks with earliest_opens to get the first open date for each user
merged_data_tracks <- tracks %>%
  left_join(earliest_opens, by = "user_id")

# Define cutoff dates
cutoff_date_1 <- as.POSIXct("2024-07-16 00:00:00", tz = "UTC")
cutoff_date_2 <- as.POSIXct("2024-08-14 00:00:00", tz = "UTC")

# Create a new column to classify users based on their first app open date

merged_data_tracks$group <- ifelse(
  merged_data_tracks$earliest_device_time >= cutoff_date_1 & merged_data_tracks$earliest_device_time < cutoff_date_2,
  "July20_Aug13",
  ifelse(
    merged_data_tracks$earliest_device_time >= cutoff_date_2,
    "Aug14_After",
    NA_character_
  )
)

# Define the cutoff date for excluding tracks
cutoff_date_exclude <- as.POSIXct("2024-07-18 00:00:00", tz = "UTC")

# Filter merged_data to exclude rows with created_date before July 18th
merged_data_filtered <- merged_data_tracks %>%
  filter(created_date >= cutoff_date_exclude)

merged_data_tracks <- merged_data_filtered

# Calculate the end of the 14-day period for each user
merged_data_tracks <- merged_data_tracks %>%
  mutate(end_date = earliest_device_time + days(14))

# Check the end dates
#print("Merged Data with End Dates")
#print(head(merged_data_tracks))
#print(table(merged_data_tracks$end_date))

# Filter the tracks data to include only the activities within the 14-day window
activity_data <- merged_data_tracks %>%
  filter(created_date >= earliest_device_time & created_date <= end_date)

# Convert 'file_duration' to numeric if it's not already
activity_data <- activity_data %>%
  mutate(file_duration = as.numeric(file_duration))

# Check the type again to confirm conversion
print("File Duration Conversion")
## [1] "File Duration Conversion"
print(str(activity_data$file_duration))
##  num [1:5370] 181237 181002 181603 301531 301688 ...
## NULL
print(summary(activity_data$file_duration))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0  298680  520008  574157  638520 5497887
# Sum the duration of activities within the 14-day window for each user
activity_summary <- activity_data %>%
  group_by(user_id, group) %>%
  summarise(total_duration = sum(file_duration, na.rm = TRUE), .groups = 'drop')

# Convert total_duration from milliseconds to minutes
activity_summary <- activity_summary %>%
  mutate(total_duration_minutes = total_duration / 60000)

# Check the activity summary
print("Activity Summary")
## [1] "Activity Summary"
#print(head(activity_summary))

# Compare the two groups
summary_stats <- activity_summary %>%
  group_by(group) %>%
  summarise(
    mean_duration = mean(total_duration_minutes, na.rm = TRUE),
    sd_duration = sd(total_duration_minutes, na.rm = TRUE),
    count = n(),
    .groups = 'drop'
  )

# Print summary statistics
print("Summary Statistics")
## [1] "Summary Statistics"
print(summary_stats)
## # A tibble: 2 × 4
##   group        mean_duration sd_duration count
##   <chr>                <dbl>       <dbl> <int>
## 1 Aug14_After           56.3        71.7   139
## 2 July20_Aug13          68.6       100.    635
# Perform a t-test to compare total durations (in minutes) between the two groups
t_test_result <- t.test(total_duration_minutes ~ group, data = activity_summary)


# Print the results of the t-test
print(t_test_result)
## 
##  Welch Two Sample t-test
## 
## data:  total_duration_minutes by group
## t = -1.6998, df = 271.47, p-value = 0.09031
## alternative hypothesis: true difference in means between group Aug14_After and group July20_Aug13 is not equal to 0
## 95 percent confidence interval:
##  -26.667150   1.954804
## sample estimates:
##  mean in group Aug14_After mean in group July20_Aug13 
##                   56.25443                   68.61060
# For tracks
if (!inherits(tracks_started$created, "POSIXct")) {
  tracks_started <- tracks_started %>%
    mutate(created_date = as.POSIXct(created / 1000, origin = "1970-01-01", tz = "UTC"))
}

# Merge tracks_started with earliest_opens to get the first open date for each user
merged_starts <- tracks_started %>%
  left_join(earliest_opens, by = "user_id")

# Create a new column to classify users based on their first app open date
merged_starts$group <- ifelse(
  merged_starts$earliest_device_time >= cutoff_date_1 & merged_starts$earliest_device_time < cutoff_date_2,
  "July20_Aug13",
  ifelse(
    merged_starts$earliest_device_time >= cutoff_date_2,
    "Aug14_After",
    NA_character_
  )
)


# Calculate the end of the 14-day period for each user
merged_starts <- merged_starts %>%
  mutate(end_date = earliest_device_time + days(14))

# Filter the tracks_started data to include only the activities within the 14-day window
activity_data_starts <- merged_starts %>%
  filter(created_date >= earliest_device_time & created_date <= end_date)

# Keep only the rows in activity_data_starts where user_id is present in filtered_tracks
cleaned_activity_data_starts <- activity_data_starts %>%
  semi_join(filtered_tracks, by = "user_id")

activity_data_starts <- cleaned_activity_data_starts

# Convert 'file_duration' to numeric if it's not already
activity_data_starts <- activity_data_starts %>%
  mutate(file_duration = as.numeric(file_duration))

# Sum the duration of activities within the 14-day window for each user in activity_data_starts
# Sum the duration of activities within the 14-day window for each user in activity_data_starts
activity_summary_starts <- activity_data_starts %>%
  group_by(user_id, group) %>%
  summarise(total_duration_starts = sum(file_duration, na.rm = TRUE), .groups = 'drop')

# Convert total_duration_starts from milliseconds to minutes
activity_summary_starts <- activity_summary_starts %>%
  mutate(total_duration_starts_minutes = total_duration_starts / 60000)

# Merge activity_summary and activity_summary_starts to compare durations
comparison_summary <- activity_summary %>%
  full_join(activity_summary_starts, by = c("user_id", "group")) %>%
  mutate(
    difference = total_duration_minutes - total_duration_starts_minutes
  )

# Calculate summary statistics including the proportion of started to completed durations
summary_comparison <- comparison_summary %>%
  group_by(group) %>%
  summarise(
    mean_completed_duration = mean(total_duration_minutes, na.rm = TRUE),
    mean_started_duration = mean(total_duration_starts_minutes, na.rm = TRUE),
    proportion_started_of_completed = (mean_completed_duration / mean_started_duration) * 100,
    sd_completed_duration = sd(total_duration_minutes, na.rm = TRUE),
    sd_started_duration = sd(total_duration_starts_minutes, na.rm = TRUE),
    count = n(),
    .groups = 'drop'
  )

# Print the summary statistics for the differences and proportions
print("Summary Statistics for Differences between Completed and Started Activities")
## [1] "Summary Statistics for Differences between Completed and Started Activities"
print(summary_comparison)
## # A tibble: 2 × 7
##   group      mean_completed_durat…¹ mean_started_duration proportion_started_o…²
##   <chr>                       <dbl>                 <dbl>                  <dbl>
## 1 Aug14_Aft…                   56.3                  71.5                   78.6
## 2 July20_Au…                   68.6                  92.0                   74.6
## # ℹ abbreviated names: ¹​mean_completed_duration,
## #   ²​proportion_started_of_completed
## # ℹ 3 more variables: sd_completed_duration <dbl>, sd_started_duration <dbl>,
## #   count <int>
# Count the number of tracks started for each user and group
tracks_started_count <- activity_data_starts %>%
  group_by(user_id, group) %>%
  summarise(total_tracks_started = n(), .groups = 'drop')

# Count the number of tracks completed for each user and group
tracks_completed_count <- merged_data_tracks %>%
  group_by(user_id, group) %>%
  summarise(total_tracks_completed = n(), .groups = 'drop')

library(tidyr)
# Merge the counts by user_id and group
comparison_counts <- tracks_started_count %>%
  full_join(tracks_completed_count, by = c("user_id", "group")) %>%
  replace_na(list(total_tracks_started = 0, total_tracks_completed = 0))

# Calculate the proportion of tracks started to tracks completed
comparison_counts <- comparison_counts %>%
  mutate(
    proportion_started_to_completed = ifelse(total_tracks_completed > 0, 
                                              total_tracks_started / total_tracks_completed, 
                                              0)  # Avoid division by zero
  )

# Summarize the proportions by group
summary_proportions <- comparison_counts %>%
  group_by(group) %>%
  summarise(
    mean_proportion = mean(proportion_started_to_completed, na.rm = TRUE),
    sd_proportion = sd(proportion_started_to_completed, na.rm = TRUE),
    count = n(),
    .groups = 'drop'
  )

# Print the summary of proportions
print("Summary of Proportions")
## [1] "Summary of Proportions"
print(summary_proportions)
## # A tibble: 2 × 4
##   group        mean_proportion sd_proportion count
##   <chr>                  <dbl>         <dbl> <int>
## 1 Aug14_After            0.686          1.07   155
## 2 July20_Aug13           0.618          1.03   717
# Filter out NA or constant values before the t-test
valid_comparison_counts <- comparison_counts %>%
  filter(!is.na(proportion_started_to_completed) & total_tracks_completed > 0)

# Perform a t-test to compare the proportions between the two groups
if (nrow(valid_comparison_counts) > 0) {
  t_test_result <- t.test(proportion_started_to_completed ~ group, data = valid_comparison_counts)
  
  # Print the results of the t-test
  print(t_test_result)
} else {
  print("Not enough valid data for t-test.")
}
## 
##  Welch Two Sample t-test
## 
## data:  proportion_started_to_completed by group
## t = 0.98403, df = 196.26, p-value = 0.3263
## alternative hypothesis: true difference in means between group Aug14_After and group July20_Aug13 is not equal to 0
## 95 percent confidence interval:
##  -0.1001134  0.2995155
## sample estimates:
##  mean in group Aug14_After mean in group July20_Aug13 
##                  0.7597600                  0.6600589
library(dplyr)

# Assuming both dataframes have a user_id column to join on

# 1. Prepare tracks_completed_count by user
#completed_by_user <- tracks_completed_count %>%
 # group_by(user_id, group) %>%
#  summarise(total_completed = sum(total_tracks_completed, na.rm = TRUE), .groups = 'drop')

# 2. Prepare tracks_started_count by user
#started_by_user <- tracks_started_count %>%
#  group_by(user_id, group) %>%
#  summarise(total_started = sum(total_tracks_started, na.rm = TRUE), .groups = 'drop')

# 3. Merge the completed and started data by user and group
merged_data_start_comp <- tracks_completed_count %>%
  inner_join(tracks_started_count, by = c("user_id", "group"))

# 4. Correlate total completed vs total started for each group
correlation_results <- merged_data_start_comp %>%
  group_by(group) %>%
  summarise(
    correlation = cor(total_tracks_completed, total_tracks_started, method = "pearson", use = "complete.obs"),
    p_value = cor.test(total_tracks_completed, total_tracks_started, method = "pearson", use = "complete.obs")$p.value,
    .groups = 'drop'
  )

# Print the correlation results by group
print(correlation_results)
## # A tibble: 2 × 3
##   group        correlation  p_value
##   <chr>              <dbl>    <dbl>
## 1 Aug14_After        0.914 1.73e-27
## 2 July20_Aug13       0.556 2.88e-37
# ERROR: Check that both time periods are filtered to 14 days? 
# I.e. are the correlations between tracks started and completed in each time frame (affected = July 20 - Aug 13) and unaffected (Aug14_after) statistically different? 
# This is for the count of tracks completed/started, not duration of file 

# Define the correlation
r1 <- 0.9135752
r2 <- 0.5557390  # correlation from group 2

# Fisher r-to-z transformation function
fisher_r_to_z <- function(r) {
  z <- 0.5 * log((1 + r) / (1 - r))
  return(z)
}

# Apply the transformation to both correlations
z1 <- fisher_r_to_z(r1)
z2 <- fisher_r_to_z(r2)

# Output the z-values
z1
## [1] 1.548727
z2
## [1] 0.6266469
# Define sample sizes
n1 <- 155
n2 <- 717

# Standard error calculation
SE1 <- 1 / sqrt(n1 - 3)
SE2 <- 1 / sqrt(n2 - 3)

# Calculate the z-statistic for comparison
z_diff <- (z1 - z2) / sqrt(SE1^2 + SE2^2)

# Output the z-statistic
z_diff
## [1] 10.3224
# Calculate the p-value for a two-tailed test
p_value <- 2 * pnorm(-abs(z_diff))
p_value
## [1] 5.581145e-25
# Extract IDs from each group in activity_summary
july20_aug13_ids <- activity_summary %>%
  filter(group == "July20_Aug13") %>%
  select(user_id)

aug14_after_ids <- activity_summary %>%
  filter(group == "Aug14_After") %>%
  select(user_id)

# Join these IDs with df_stats to pull relevant stats for each group
july20_aug13_stats <- stats_filtered %>%
  filter(user_id %in% july20_aug13_ids$user_id)

aug14_after_stats<- stats_filtered %>%
  filter(user_id %in% aug14_after_ids$user_id)
# Join df_stats with activity_summary to bring in the group information

#df_stats_grouped <- df_stats %>%
#  inner_join(activity_summary %>% select(user_id, group), by = "user_id")
# Extract IDs for each group from activity_summary
july20_aug13_ids <- activity_summary %>%
  filter(group == "July20_Aug13") %>%
  select(user_id)

aug14_after_ids <- activity_summary %>%
  filter(group == "Aug14_After") %>%
  select(user_id)

# Filter stats for each group based on the extracted IDs
july20_aug13_stats <-  stats_filtered %>%
  filter(user_id %in% july20_aug13_ids$user_id)

aug14_after_stats <- stats_filtered %>%
  filter(user_id %in% aug14_after_ids$user_id)

# Calculate summary statistics for July20_Aug13 group
july20_aug13_summary <- july20_aug13_stats %>%
  summarise(
    mean_tracks_started = mean(tracks_started, na.rm = TRUE),
    sd_tracks_started = sd(tracks_started, na.rm = TRUE),
    
    mean_tracks_completed = mean(tracks_completed, na.rm = TRUE),
    sd_tracks_completed = sd(tracks_completed, na.rm = TRUE),
    
    mean_time_listened = mean(time_listened, na.rm = TRUE),
    sd_time_listened = sd(time_listened, na.rm = TRUE),
    
    mean_streak_longest = mean(streak_longest, na.rm = TRUE),
    sd_streak_longest = sd(streak_longest, na.rm = TRUE)
  )

# Calculate summary statistics for Aug14_After group
aug14_after_summary <- aug14_after_stats %>%
  summarise(
    mean_tracks_started = mean(tracks_started, na.rm = TRUE),
    sd_tracks_started = sd(tracks_started, na.rm = TRUE),
    
    mean_tracks_completed = mean(tracks_completed, na.rm = TRUE),
    sd_tracks_completed = sd(tracks_completed, na.rm = TRUE),
    
    mean_time_listened = mean(time_listened, na.rm = TRUE),
    sd_time_listened = sd(time_listened, na.rm = TRUE),
    
    mean_streak_longest = mean(streak_longest, na.rm = TRUE),
    sd_streak_longest = sd(streak_longest, na.rm = TRUE)
  )

# Combine summaries into a single table with separate columns for each group# Create a comparison table with formatted numbers
comparison_table <- data.frame(
  Metric = c("Tracks Started", "Tracks Completed", "Time Listened", "Longest Streak"),
  
  July20_Aug13_Mean = format(c(july20_aug13_summary$mean_tracks_started,
                               july20_aug13_summary$mean_tracks_completed,
                               july20_aug13_summary$mean_time_listened,
                               july20_aug13_summary$mean_streak_longest), 
                             scientific = FALSE),
  
  July20_Aug13_SD = format(c(july20_aug13_summary$sd_tracks_started,
                             july20_aug13_summary$sd_tracks_completed,
                             july20_aug13_summary$sd_time_listened,
                             july20_aug13_summary$sd_streak_longest), 
                           scientific = FALSE),
  
  Aug14_After_Mean = format(c(aug14_after_summary$mean_tracks_started,
                              aug14_after_summary$mean_tracks_completed,
                              aug14_after_summary$mean_time_listened,
                              aug14_after_summary$mean_streak_longest), 
                            scientific = FALSE),
  
  Aug14_After_SD = format(c(aug14_after_summary$sd_tracks_started,
                            aug14_after_summary$sd_tracks_completed,
                            aug14_after_summary$sd_time_listened,
                            aug14_after_summary$sd_streak_longest), 
                          scientific = FALSE)
)

# Print the comparison table
print("Comparison Table of Summary Statistics")
print(comparison_table)

# Less for Aug 14 and after - but they've collected less data by Sep 5 date we got sent the data. I've filtered out non-new users but hard to compare after Aug 14 to before because stats are totals.