How do I count thee? Let me count the ways?

My other girlfriend, Irmaa. (Not a typo: two a's)

            She is lovely, isn't she?       Irmaa sat alone at a corner table in the kind of restaurant where th...

Sunday, February 1, 2026

My other girlfriend, Irmaa. (Not a typo: two a's)

     
      She is lovely, isn't she?

      Irmaa sat alone at a corner table in the kind of restaurant where the silverware had weight and the waiters moved like well trained ghosts. A single glass of Sancerre caught the light, throwing a pale shimmer across the white tablecloth. She liked that — the quiet glow, the sense that even photons paused to admire her.

      Her simple but elegant hairstyle, with a few intentional strands of silver, framed a face that could shift from stern to playful in a heartbeat. Tonight it hovered somewhere in between. She tapped a manicured finger against the stem of her glass, scanning the room with the calm confidence of someone who knew she brought in more revenue than most small nations.

      The maĆ®tre d’ approached with a deferential smile. “Will anyone be joining you this evening, Ms. Irmaa?”

      She returned the smile, subtle and knowing. “Oh, people join me every year,” she said, “but never at the same table.”

So who is Irmaa?

      My real significant other girlfriend knows one of my life philosophies is "You can only have one Honey." When I am watching TV or a movie, and a character who already has a partner starts looking for a second partner, I predict bad things will happen. Male or female, straight or gay, it doesn't matter. "You can only have one Honey."

      And true to my philosophy, I have, reluctantly, added Irmaa to my life, and bad things have happened. Sigh.

      IRMAA stands for Income-Related Monthly Adjustment Amount. It is a surcharge directly deducted from your Social Security check, and added to Medicare Part B and Part D premiums for beneficiaries with higher incomes. IRMAA generates tens of billions of dollars each year. IRMAA premiums are slated to rise 30 percent from 2026 to 2030, according to the 2025 Medicare Trustees Report. In comparison the Social Security cost of living adjustment was set at 2.8 percent for 2026. See IRMAA.

      My IRMAA surcharge is quite large relative to my standard Medicare premium.

      If you imagine IRMAA as a single individual collecting all those surcharges herself, she’d be pulling in revenue on the scale of tech billionaires. IRMAA as a person would be staggeringly wealthy.

      I think of her as my girlfriend named Irmaa. I am one of those who pays for her extravagant lifestyle. She takes and takes, and does not give much back. Of course, she has quite a few other boyfriends. And girlfriends.

      Irma (single a) is a quite uncommon name nowadays. Irma is currently #2609 in U.S. births according to The Bump's Data. The World Meteorological Organization retired Irma as an Atlantic hurricane name after its disasterous 2017 hurricane, feeling the future use of the name would be insensitive.

.       Meanwhile Irma calmly enjoys her expensive meals, confidently knowing over 5 million Medicare beneficiaries - men and women - support her lifestyle. She's not your girlfriend yet? Just wait a few years.

      (Photo from Google Gemini, description of Irmaa by me in consultation with Microsoft Copilot.)

Sunday, January 25, 2026

Do prices feel like they are rising more than the CPI says?

      Do prices feel like they are rising more than the CPI (Consumer Price Index) says? Yes.

      For 2025 the overall CPI increased by a pretty moderate 2.7% (CPI-U for all urban consumers, December to December). The CPI measures the price change of a basket of goods over eight major categories: food & beverages, housing, apparel, transportation, medical care, recreation, education & communication, and other, over a large number of metropolitan statitical areas (MSA). Each month Bureau of Labor Statistics data collectors collect about 94,000 prices. For some items, prices are adjusted to remove the effect of a change of quality (for example today's Toyota Corolla is a much different car than ten years ago). There are separate indices for over 200 items countrywide, and separate indices for the eight major categories by MSA.

      Of course what matters is price changes on the items YOU buy, and especially the items you buy frequently like food. Each individual item has its own reasons for its price changes - egg prices are affected by bird flu, coffee prices are affected by weather and geopolitical conditions in other countries, etc. These factors are beyond our control.

      I was interested in comparing food price changes for common frequently purchased items. This is based on CPIs for countrywide data in categories like eggs. Of course I am not measuring YOUR specific egg purchase (such as store brand, organic, medium size, white, 12 count, at CTown in Intercourse, Pennsylvania).

      I began with 11 years of December values of ten separate food categories and also the overall CPI-U, seasonally adjusted. The values I used are as follows (although I understand values change as there are changes to seasonal adjustment factors, weightings, etc.)

      For comparison purposes I set all eleven indices to a 100 index value at 2015, and I plotted them on a line graph. Each year's value is now relative to 2015.

      On a ten-year basis, ground beef, eggs, and lettuce are running higher than the overall CPI. Those three food indices have experienced a lot of volatility. The pandemic year 2022 was the year of the largest increase for many foods. Interestingly, apple prices have gone down!

      Another way to look at this is to look at bar graphs with percentage changes. Here are graphs with percentage changes 2015 to 2025, 2024 to 2025, and 2021 to 2022:

      For 2025 compared with 2015, I was not aware how much the prices had risen for ground beef, lettuce, and eggs.

      For 2025 compared to 2024, the increase in prices for ground beef, eggs, and coffee have been much larger than the 2.7% overall increase in the CPI. This is probably no surprise if you are the household member doing the grocery shopping.

      For 2022 versus 2021, the increase in all foods except ground beef exceeded the overall CPI. We probably remember this during the Covid pandemic years.

      In the insurance world, the goods and services that insurance pays for have also increased by more than the overall CPI. For example, medical care costs, auto maintenance & repair costs, and building construction & repair costs have consistently outpaced the overall CPI. So don't be surprised to see health insurance, auto insurance, and home insurance prices to continue to increase.

      Here is the R code:


library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)

df <- read_excel("C:/Users/Jerry/Desktop/R_files/CPI_10_years.xlsx")
print(df, n = Inf, width = Inf)

# 1. Convert data to 'long' format for easier plotting
df_long <- df %>%
  pivot_longer(cols = -Year, names_to = "Category", values_to = "Index")

# 2. Re-base every category so 2015 = 100
df_normalized <- df_long %>%
  group_by(Category) %>%
  mutate(Index_100 = (Index / Index[Year == 2015]) * 100) %>%
  ungroup()

# 3. Plot line graph "Race to the Top"
ggplot(df_normalized, aes(x = Year, y = Index_100, color = Category)) +
  geom_line(aes(size = Category == "Overall CPI"), show.legend = FALSE) +
  # Use subset to only label the last point (2025)
  geom_text(data = subset(df_normalized, Year == 2025), 
            aes(label = Category), 
            hjust = -0.1,  # Push text to the right of the point
            size = 4, fontface="bold",
            show.legend = FALSE) +
  # Fix X-Axis: No decimals, every year labeled
  scale_x_continuous(breaks = seq(2015, 2025, 1), limits = c(2015, 2027)) +
  # Highlight the Overall CPI in black/thicker line
  scale_size_manual(values = c("TRUE" = 2.0, "FALSE" = 0.8)) +
  scale_color_manual(values = c("Overall CPI" = "black", 
                                "Eggs" = "red", 
                                "Ground Beef" = "darkred",
                                "Apples" = "forestgreen",
                                "Milk" = "blue",
                                "Bread" = "orange",
                                "Coffee" = "brown",
                                "Lettuce" = "lightgreen",
                                "Soup" = "#008080",
                                "Breakfast Cereal" = "purple",
                                "Other Fresh Veg" = "gray")) +
  theme_minimal() +
  theme(
    legend.position = "none",        # Remove legend
    plot.title = element_text(face = "bold", size = 16), 
    axis.title = element_text(face = "bold"), 
    axis.text = element_text(face = "bold"),
    plot.margin = margin(r = 100),   # Add space on the right for labels
    panel.grid.minor = element_blank()
  ) +
  coord_cartesian(clip = 'off') +    # Prevent labels from being cut off
  labs(title = "Cumulative Food Price Changes (2015 = 100)",
       subtitle = "Food categories vs. Overall CPI Baseline",
       y = "Index (2015 = 100)",
       x = "Year")

#4 Plot bar graph with % changes
# filter data for start and end years 

plot_cpi_change <- function(data, start_yr, end_yr) {
  
  # 1. Prepare dynamic column names for the mutation step
  start_col <- paste0("Yr", start_yr)
  end_col <- paste0("Yr", end_yr)
  
  # 2. Data Processing
  df_bar <- data %>% 
    filter(Year %in% c(start_yr, end_yr)) %>%
    pivot_longer(cols = -Year, names_to = "Category", values_to = "Index") %>% 
    pivot_wider(names_from = Year, names_prefix = "Yr", values_from = Index) %>%
    # Use .data[[]] to dynamically reference the columns created by pivot_wider
    mutate(Pct_Change = ((.data[[end_col]] - .data[[start_col]]) / .data[[start_col]]) * 100) %>%
    mutate(Category = reorder(Category, -Pct_Change))
  
  # 3. Visualization
  ggplot(df_bar, aes(x = Category, y = Pct_Change, fill = Category)) +
    geom_bar(stat = "identity", color = "black", size = 0.5) +
    # Logic for text placement based on positive/negative change
    geom_text(aes(label = paste0(round(Pct_Change, 1), "%"),
                  vjust = ifelse(Pct_Change >= 0, -0.5, 1.5)), 
              fontface = "bold", size = 4.5) +
    scale_fill_manual(values = c("Overall CPI" = "black", "Soup" = "#008080", "Eggs" = "red", 
                                 "Ground Beef" = "darkred", "Apples" = "forestgreen", "Milk" = "blue", 
                                 "Bread" = "orange", "Coffee" = "brown", "Lettuce" = "lightgreen", 
                                 "Breakfast Cereal" = "purple", "Other Fresh Veg" = "gray")) +
    theme_minimal() + 
    theme(legend.position = "none", 
          plot.title = element_text(face = "bold", size = 18, hjust = 0.5), 
          axis.title = element_text(face = "bold", size = 14), 
          axis.text.x = element_text(face = "bold", size = 11, angle = 45, hjust = 1), 
          axis.text.y = element_text(face = "bold", size = 11), 
          panel.grid.major.x = element_blank()) +
    coord_cartesian(clip = 'off') +
    labs(title = paste("CPI FOOD PRICE CHANGES (", start_yr, "TO", end_yr, ")"), 
         y = "PERCENT CHANGE (%)", x = "CATEGORY")
}

plot_cpi_change(df, 2015, 2025)
plot_cpi_change(df, 2024, 2025)
plot_cpi_change(df, 2021, 2022)

End

Friday, January 2, 2026

As the red line clearly demonstrates, ...

      I have been at lots of business meetings where the speaker would say something like, "As the red line clearly demonstrates, ..."

      I would quickly look up at two particular co-workers. We all had that same rolling of the eyes look. When you have color-challenged issues, that red line does not clearly demonstrate anything to us. (And yes, the three of us knew we all had color issues.)

      I wrote the R code for this graph. But I used a random number to decide which line is red and which is green, so I don't know which line is which.

      I am not color-blind. I am color-challenged. I see some colors, but probably not as many as most people see. I don't distinguish between red and green well. I also don't distinguish between blue and purple well because of the red element of purple, and similarly for other combinations.

      In my earliest elementary school years I had a box of 8 Crayola crayons, and I did just fine. My problems began when Crayola started adding more and more colors including combinations like green yellow and yellow green. Here are the original eight colors, which I still identify just fine. (There is no meaning to the heights of the bars.)

      One source suggests approximately 1 in 12 men have color issues, but only 1 in 200 women.

      Color-challenged people often have coping strategies. I can see when the top traffic light is on, so I will stop my car. But in my heart, I don't think it is red, but more of an orange. Similarly I can see when the bottom traffic light is on, but I think it is more of an off-white than green. As long as no one flips the positions, I am fine. A single flashing light is a probllem though.

      When I see an 8-sided stop sign, that's what I consider red. And I recognize Taylor Swift wears what I consider a very red lipstick, but I assume she wears more than one shade and I cannot distinguish among them.

      The speaker with the two-line graph could have used the different shapes, or different graph line types dashes and dots, in the talk. Or the speaker could have used color-blind friendly color palettes. If you are creating visualizations for others, please think about these things.

      And ladies, that purple lipstick looks very nice on you. Oh, it's not purple ... ?

      The R code is as follows:





# Two lines with random colors
x <- seq(1:5)
y <- seq(1:5)
z <- seq(5,1, by = -1)

color_1 <- "#00B050"
color_2 <- "#FF0000" 

r <- runif(1,0,1)
r
if (r < .5){
  col_y <- color_1
  col_z <- color_2
} else{
  col_y <- color_2
  col_z <- color_1
}

plot(x,y, type="b", pch = 18, cex = 2.5, lwd = 2.5, col=col_y, ylab="", xlab="", 
     main="As the red line clearly demonstrates ...", cex.main = 1.5,
     sub="If r<.5 then (green, red), else (red, green)",
     font.sub = 2, cex.sub = 1.5)
par(new=TRUE)
plot(x,z, type="b", pch=20, cex = 2.5, lwd = 2.5, col=col_z, ylab="", xlab="")
legend("topright", legend= c("Increasing", "Decreasing"), pch = c(18, 20),
       col = c(col_y, col_z), cex=1.5, text.font=2)

# Original 8 Crayola Crayons
title <- c("Original 8 Crayola Crayons")
subtitle <- c("According to https://en.wikipedia.org/wiki/History_of_Crayola_crayons")
temp <- c(5,7,6,4,8,5,2,5)  # meaningless
colors <- c("red", "yellow", "blue", "green", "orange", "brown", "violet", "black")
hex <- c("#FF0000", "#FFFF00", "#0000FF", "#008001", "#FF6600", "#964B00", "#6A0DAD", "#000000")
barplot(temp, col=hex, main=title, sub=subtitle, names.arg=colors,
          cex.main = 1.5, font.axis = 2, font.sub = 2, cex.sub = .75 )
       
End