# Load packages and prepare data
suppressPackageStartupMessages(library(tidyverse))
library(haven)
library(knitr)
suppressPackageStartupMessages(library(kableExtra))

file_path <- "C:/Users/JH/Kitces.com/DV - Research/Anonymized Data and Codebooks - All Projects/AdvisorTech Studies/2025/tech 25.dta"
df <- haven::read_dta(file_path)

df_clean <- df %>%
 filter(!is.na(fpprsuse)) %>%  
 mutate(
# Current use 
curr_emoney = (fpprssw1 == 9 | fpprssw2 == 9),
curr_moneyguide  = (fpprssw1 == 15 | fpprssw2 == 15),
curr_rightcapital = (fpprssw1 == 23 | fpprssw2 == 23),
# Future
future = case_when(
fpfutsw ==  9 ~ "eMoney",
fpfutsw == 15 ~ "MoneyGuide",
fpfutsw == 23 ~ "RightCapital",
TRUE  ~ "Other/missing"
)
  )
total_sample <- nrow(df_clean)

# Summary table
summary_table <- tibble(
Category = c(
"Total advisors who answered the FP software use question",
"Total users of eMoney (primary or secondary)",
"Total users of MoneyGuidePro (primary or secondary)",
"Total users of RightCapital (primary or secondary)"
),
 
Count = c(
total_sample,
sum(df_clean$curr_emoney, na.rm = TRUE),
sum(df_clean$curr_moneyguide, na.rm = TRUE),
sum(df_clean$curr_rightcapital, na.rm = TRUE)
)
) %>%
mutate(
Percent = round(Count / total_sample * 100, 1),
Percent = paste0(Percent, "%")
)
kable(summary_table,
caption = "Financial Planning Software Usage Overview",
col.names = c("Category", "Count", "Percent of Total"),
align = c("l", "r", "r"),
digits = 1) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE,
position = "left")%>%
row_spec(0, bold = TRUE, background = "#f0f8ff")  
Financial Planning Software Usage Overview
Category Count Percent of Total
Total advisors who answered the FP software use question 699 100%
Total users of eMoney (primary or secondary) 214 30.6%
Total users of MoneyGuidePro (primary or secondary) 133 19%
Total users of RightCapital (primary or secondary) 178 25.5%
knitr::asis_output("The vast majority of advisors in the sample (N = 706) report using at least one financial planning software. eMoney remains a widely adopted platform, with 30.6% of advisors using it in either primary or secondary position, far ahead of MoneyGuidePro (19%) and RightCapital (25.5%).")

The vast majority of advisors in the sample (N = 706) report using at least one financial planning software. eMoney remains a widely adopted platform, with 30.6% of advisors using it in either primary or secondary position, far ahead of MoneyGuidePro (19%) and RightCapital (25.5%).

# Table 2 Switching from current to future (percent + count)
# create the percentages
matrix_data <- tibble(
From = c("eMoney", "MoneyGuide", "RightCapital"),

`To eMoney` = c(
mean(df_clean$curr_emoney & df_clean$future == "eMoney", na.rm = TRUE) * 100,
mean(df_clean$curr_moneyguide  & df_clean$future == "eMoney", na.rm = TRUE) * 100,
mean(df_clean$curr_rightcapital & df_clean$future == "eMoney", na.rm = TRUE) * 100
),
 
`To MoneyGuide` = c(
mean(df_clean$curr_emoney & df_clean$future == "MoneyGuide", na.rm = TRUE) * 100,
mean(df_clean$curr_moneyguide  & df_clean$future == "MoneyGuide", na.rm = TRUE) * 100,
mean(df_clean$curr_rightcapital & df_clean$future == "MoneyGuide", na.rm = TRUE) * 100
),
  
`To RightCapital` = c(
mean(df_clean$curr_emoney & df_clean$future == "RightCapital", na.rm = TRUE) * 100,
mean(df_clean$curr_moneyguide  & df_clean$future == "RightCapital", na.rm = TRUE) * 100,
mean(df_clean$curr_rightcapital & df_clean$future == "RightCapital", na.rm = TRUE) * 100
)
) %>%
mutate(across(where(is.numeric), ~ round(., 1)))

# Add count in parentheses
matrix_display <- matrix_data %>%
mutate(across(
.cols = starts_with("To "),
.fns = ~ paste0(., "% (", round(. * total_sample / 100), ")")
))

kable(matrix_display,
caption = "Planned Switches to Future Financial Planning Software (Next 12 Months)",
align = c("l", "c", "c", "c"),
digits = 1) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE,
position = "left") %>%
row_spec(0, bold = TRUE, background = "#f0f8ff") %>%  
footnote(general = paste("Values show percent of all advisors (N =", total_sample, 
"), with raw count in parentheses. ",
"Current use includes primary or secondary."),
general_title = "Note: ")
Planned Switches to Future Financial Planning Software (Next 12 Months)
From To eMoney To MoneyGuide To RightCapital
eMoney 28.9% (202) 0.7% (5) 0.7% (5)
MoneyGuide 0.6% (4) 17.8% (124) 0.6% (4)
RightCapital 0.4% (3) 0.2% (1) 24.3% (170)
Note:
Values show percent of all advisors (N = 699 ), with raw count in parentheses. Current use includes primary or secondary.
knitr::asis_output("Among all advisors, the large majority who currently use eMoney plan to retain it as their primary software in the next 12 months. the case for MoneyGuidePro and RightCapital is similar. Planned switches away from current tools appear limited overall, suggesting relatively stable preferences across the three platforms..")

Among all advisors, the large majority who currently use eMoney plan to retain it as their primary software in the next 12 months. the case for MoneyGuidePro and RightCapital is similar. Planned switches away from current tools appear limited overall, suggesting relatively stable preferences across the three platforms..

# Generating plots
matrix_long <- matrix_data %>%  
pivot_longer(
cols = starts_with("To "),
names_to = "To",
values_to = "Percentage"
) %>%
mutate(
To = str_remove(To, "To "),
From = factor(From, levels = c("eMoney", "MoneyGuide", "RightCapital")),
To  = factor(To,   levels = c("eMoney", "MoneyGuide", "RightCapital"))
)
# Heatmap
ggplot(matrix_long, aes(x = To, y = From, fill = Percentage)) +
geom_tile(color = "grey80", linewidth = 0.4) +
geom_text(aes(label = paste0(Percentage, "%")), 
color = "black", size = 2.2, fontface = "bold") +
scale_fill_gradient(low = "#f0f8ff", high = "#00bfff",
limits = c(0, 30),
breaks = seq(0, 30, by = 10)) +
labs(
title = "Planned Switches to Future Financial Planning Software (Next 12 Months)",
x = "Planned Future Financial Planning Software",
y = "Current Financial Planning Software",
fill = "%"
) +
theme_minimal(base_size = 10) +
theme(
plot.title = element_text(face = "bold", size = 10, hjust = 0.5),
plot.subtitle = element_text(size = 10, hjust = 0.5, color = "grey50"),
axis.title = element_text(size = 10, face = "bold"),
axis.text = element_text(size = 9),
legend.text = element_text(size = 9),
legend.title = element_text(size = 9),
panel.grid = element_line(color = "grey92", linewidth = 0.3),
plot.margin = margin(t = 10, r = 20, b = 10, l = 10)
)

knitr::asis_output("The heatmap illustrates high retention rates for the three platforms among their respective current users, with limited cross-provider switching intent in the next 12 months.")

The heatmap illustrates high retention rates for the three platforms among their respective current users, with limited cross-provider switching intent in the next 12 months.

# Bar chart
ggplot(matrix_long, aes(x = To, y = Percentage, fill = From)) +
geom_col(position = position_dodge(width = 0.9), width = 0.8) +
geom_text(aes(label = paste0(Percentage, "%")),
position = position_dodge(0.9),
vjust = -0.4, size = 2.8, fontface = "bold") +
scale_fill_brewer(palette = "Set2", name = "") +
labs(
title = "Planned Switches to Future Financial Planning Software (Next 12 Months)",
x = "Future Financial Planning Software",
y = "Percentage of all advisors (%)"
) +
theme_minimal(base_size = 10) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5, color = "grey50"),
legend.position = "bottom",
axis.text.x = element_text(angle = 0, vjust = 0.5)
)

knitr::asis_output("The bar graph illustrates high retention rates for the three platforms among their respective current users, with limited cross-provider switching intent in the next 12 months.")

The bar graph illustrates high retention rates for the three platforms among their respective current users, with limited cross-provider switching intent in the next 12 months.