# Overall Value and Predicted Number of Fixations

    library(ggplot2)
    library(dplyr)
    library(tibble)
    library(purrr)
    library(patchwork)
    library(masc)

Predicted number of fixations as a function of overall value (controlled for value difference). Gray points show XXXX trials for XXX simulated participant and the green lines show the predicted number of fixations when value difference is fixed.

    # Function to simulate overall value effects
    simulate_overall_value_effects <- function(n_trials = 200,
                                               n_subjects = 100,
                                               thresholds = c(0.001, 0.1, 0.2)) {

      # Function to generate attribute values with controlled overall value
      generate_controlled_values <- function(n_options = 5) {
        # Generate random values initially
        values <- rnorm(n_options)
        # Calculate and adjust overall value while preserving relative differences
        overall <- mean(values)
        # Randomly shift overall value between -2 and 2
        shift <- runif(1, -4, 4)
        values + shift
      }

      # Simulate trials for each threshold value
      results <- map_dfr(thresholds, function(thresh) {
        map_dfr(1:n_subjects, function(s) {
          trials <- map_dfr(1:n_trials, function(t) {
            # Generate values with controlled overall value
            values <- generate_controlled_values()

            # Create properly formatted data frame for rMASC
            trial_data <- data.frame(
              matrix(values, nrow = 1, ncol = 5)
            )
            names(trial_data) <- paste0("opt", 1:5, "_att1")

            # Run MASC model
            trial_result <- rMASC(
              data = trial_data,
              n_options = 5,
              n_attributes = 1,
              theta = thresh,
              w = 1  # single attribute weight
            )$raw[[1]]

            # Calculate overall value and value difference
            overall_value <- mean(values)
            value_diff <- max(values) - mean(values[-which.max(values)])

            tibble(
              subject = s,
              trial = t,
              threshold = thresh,
              overall_value = overall_value,
              value_diff = value_diff,
              n_fixations = trial_result$rt,
              correct = trial_result$correct
            )
          })
        })
      })

      results
    }

    # Run simulation
    set.seed(2025)
    results <- simulate_overall_value_effects(n_trials = 200, n_subjects = 20)

    # Add threshold labels as a factor
    results <- results %>%
      mutate(threshold_label = factor(threshold,
                                      levels = c(0.001, 0.1, 0.2),
                                      labels = c("Conservative (θ = 0.001)",
                                                 "Moderate (θ = 0.1)",
                                                 "Liberal (θ = 0.2)")))

    # Add binned overall value and calculate mean consistency per bin
    results_binned <- results %>%
      mutate(value_diff = round(value_diff)) %>%
      filter(value_diff == 1) %>%
      mutate(
        correct = as.numeric(correct),  # Convert logical to numeric
        # Create bins for overall value (e.g., 20 bins)
        value_bin = cut(overall_value, breaks = 40)
      ) %>%
      group_by(threshold_label, value_bin) %>%
      summarize(
        mean_consistency = mean(correct),
        mean_value = mean(overall_value),
        n = n(),
        se = sqrt((mean_consistency * (1 - mean_consistency)) / n),
        .groups = "drop"
      )

    # Calculate regression statistics for each threshold level
    regression_stats <- results %>%
      group_by(threshold, threshold_label) %>%
      summarize(
        # Fit model controlling for value difference
        model = list(lm(n_fixations ~ overall_value + value_diff)),
        # Extract coefficient and p-value
        beta = coef(first(model))["overall_value"],
        p_value = summary(first(model))$coefficients["overall_value", "Pr(>|t|)"],
        # Get x and y positions for text
        x_pos = min(overall_value),
        y_pos = max(n_fixations),
        # Create formatted label
        stat_label = sprintf("β = %.3f\np = %.3e", beta, p_value),
        .groups = "drop"
      )

    # Calculate quadratic regression statistics
    quad_stats <- results %>%
      mutate(correct = as.numeric(correct)) %>%  # Convert logical to numeric
      group_by(threshold_label) %>%
      summarize(
        # Fit quadratic model
        model = list(lm(correct ~ overall_value + I(overall_value^2) + value_diff)),
        # Extract coefficients and p-value
        beta_linear = coef(first(model))["overall_value"],
        beta_quad = coef(first(model))["I(overall_value^2)"],
        p_value = summary(first(model))$coefficients["overall_value", "Pr(>|t|)"],
        # Get x and y positions for text
        x_pos = min(overall_value),
        y_pos = 0.95,
        # Create formatted label
        stat_label = sprintf("β1 = %.3f\nβ2 = %.3f\np = %.3e",
                             beta_linear, beta_quad, p_value),
        .groups = "drop"
      )

    p1 <- ggplot(results, aes(x = overall_value, y = n_fixations)) +
      geom_point(alpha = 0.1, size = 1) +
      geom_smooth(method = "lm",
                  formula = y ~ x,
                  color = "green",
                  se = TRUE) +
      geom_text(data = regression_stats,
                aes(x = x_pos, y = y_pos,
                    label = stat_label),
                hjust = 0, vjust = 1,
                size = 3) +
      facet_wrap(~threshold_label) +
      labs(x = "Overall Value",
           y = "Predicted Number of Fixations") +
      theme_classic() +
      theme(
        legend.position = "none",
        panel.grid.minor = element_blank(),
        strip.text = element_text(face = "bold")
      )

    p2 <- ggplot(results_binned, aes(x = mean_value, y = mean_consistency)) +
      geom_errorbar(aes(ymin = mean_consistency - se,
                        ymax = mean_consistency + se),
                    width = 0.2, alpha = 0.5) +
      geom_point(size = 2) +
      # Add quadratic fit
      geom_smooth(data = results %>% mutate(correct = as.numeric(correct)),
                  aes(x = overall_value, y = correct),
                  method = "lm",
                  formula = y ~ poly(x, 2),
                  color = "red",
                  se = TRUE) +
      geom_smooth(data = results %>% mutate(correct = as.numeric(correct)),
                  aes(x = overall_value, y = correct),
                  method = "lm",
                  formula = y ~ x,
                  color = "blue",
                  se = TRUE) +
      geom_text(data = quad_stats,
                aes(x = x_pos, y = y_pos,
                    label = stat_label),
                hjust = 0, vjust = 1,
                size = 3) +
      facet_wrap(~threshold_label) +
      labs(x = "Overall Value",
           y = "Choice Consistency",
           caption = "value difference fixed at 1") +
      scale_y_continuous(limits = c(0, 1)) +
      geom_vline(xintercept = 0, linetype = "dashed", color = "grey")+
      theme_classic() +
      theme(
        legend.position = "none",
        panel.grid.minor = element_blank(),
        strip.text = element_text(face = "bold")
      )

    # Combine plots
    combined_plot <- p1 / p2 +
      plot_layout(heights = c(1, 1)) +
      plot_annotation(
        title = "Overall Value Effects on Fixations and Choice Consistency",
        theme = theme(plot.title = element_text(size = 14, face = "bold"))
      )

    print(combined_plot)
    #> Warning: Removed 17 rows containing missing values or values outside the scale range
    #> (`geom_smooth()`).
    #> Warning: Removed 1 row containing missing values or values outside the scale range
    #> (`geom_smooth()`).