Unlocking the Highest-Paying Dividend Stocks with R

Data Visualization
Finance
Author

Wlademir Ribeiro Prates

Published

October 9, 2023

Investing in stocks is more than just looking at price appreciation. Dividends are a crucial part of the equation.

Especially for investors who prioritize income generation, knowing the dividends a stock yields year-over-year can be invaluable. In this post, I’ll guide you through a streamlined method using R to pull yearly dividend data for any stock.

Dividends are payments made by corporations to their shareholders, often as a distribution of profits. When analyzing stocks from a long-term perspective, dividends can make a significant difference in the total returns an investor receives.

In this blog post, you will discover:

R tools and techniques covered here:

Recently I’ve posted a video on my YouTube channel about this subject. If you are Portuguese speaker (or want to try the automated subtitles) please check it out. But the same content is also available here in this blog post, even with more details.

Fetching Yearly Dividends

To get yearly dividends for a stock, we make use of the quantmod package which interfaces with various sources online to fetch stock data. Here’s the code chunk to pull yearly dividends:

library(quantmod)
library(dplyr)

get_yearly_dividends <- function(ticker, years) {
  historical_dividends <- quantmod::getDividends(
    Symbol = ticker,
    from = paste0(min(years), "-01-01"),
    to = paste0(max(years), "-12-31")
  ) |>
    setNames("dividends")
  
  yearly_data <- historical_dividends |>
    dplyr::as_tibble(rownames = "date") |>
    dplyr::mutate(
      ticker = gsub(".SA", "", ticker),
      year = lubridate::year(date)
    ) |>
    group_by(year) |>
    dplyr::summarise(
      dividends = sum(dividends)
    )
  
  return(yearly_data)
}

# Example for Coca-Cola Co.
get_yearly_dividends("KO", c(2020:2023))
# A tibble: 4 × 2
   year dividends
  <dbl>     <dbl>
1  2020      1.64
2  2021      1.68
3  2022      1.76
4  2023      1.38

Getting Yearly Closing Price

While dividends tell half the story, to evaluate the attractiveness of the dividends, we need to know at what price the stock closed at the end of each year. Here’s how we can fetch that data:

get_yearly_closing_price <- function(ticker, years) {
  historical_prices <- quantmod::getSymbols(
    Symbol = ticker,
    from = paste0(min(years), "-01-01"),
    to = paste0(max(years), "-12-31"),
    auto.assign = FALSE
  ) |>
    dplyr::as_tibble(rownames = "date") |>
    dplyr::select(date, tidyr::contains("Adjusted")) |>
    setNames(c("date", "price")) |>
    dplyr::mutate(
      ticker = gsub(".SA", "", ticker),
      year = lubridate::year(date)
    ) |>
    group_by(year) |>
    dplyr::summarise(
      price = last(price)
    )
  return(historical_prices)
}

# Example for Coca-Cola Co.
get_yearly_closing_price("KO", c(2020:2023))
# A tibble: 4 × 2
   year price
  <dbl> <dbl>
1  2020  50.5
2  2021  56.2
3  2022  62.2
4  2023  52.5

Calculating Yearly Yield

Combining the dividends and the closing price, we can calculate the yield for the stock year-over-year:

get_yearly_yield <- function(ticker, years) {
  yearly_yields <- get_yearly_dividends(ticker, years) |>
    dplyr::left_join(
      get_yearly_closing_price(ticker, years),
      by = "year"
    ) |>
    dplyr::mutate(
      ticker = gsub(".SA", "", ticker),
      yield = round(100 * dividends / price, 4)
    )
  
  return(yearly_yields)
}

# Example for Coca-Cola Co.
get_yearly_yield("KO", c(2020:2023))
# A tibble: 4 × 5
   year dividends price ticker yield
  <dbl>     <dbl> <dbl> <chr>  <dbl>
1  2020      1.64  50.5 KO      3.25
2  2021      1.68  56.2 KO      2.99
3  2022      1.76  62.2 KO      2.83
4  2023      1.38  52.5 KO      2.63

Practical Examples

In this section, we will select various tickers, gather their data, and then filter for stocks that consistently paid dividends throughout our chosen period. Additionally, we’ll set a threshold to only include stocks with an average yearly dividend yield of 8% or higher.

We’ll demonstrate this approach using both American and Brazilian stocks.

Let’s apply this example to some American stocks, and also to some Brazillian stocks.

Yearly Dividend Yield Analysis for Selected - American Stocks

Tickers extracted from these blog posts: US News; NerdWallet

library(purrr)

tickers <- c(
  "XOM", # Exxon Mobil Corp.
  "KO", # Coca-Cola Co. 
  "PFE", # Pfizer Inc.
  "WFC", # Wells Fargo & Co.
  "KMB", # Kimberly-Clark Corp.
  "PDM",  # Piedmont Office Realty Trust Inc
  "BGFV", # Big 5 Sporting Goods Corp
  "ARI",  # Apollo Commercial Real Estate Finance Inc
  "REFI", # Chicago Atlantic Real Estate Finance Inc
  "DX",   # Dynex Capital, Inc.
  "BRBS", # Blue Ridge Bankshares Inc (VA)
  "CFFN", # Capitol Federal Financial
  "RGR",  # Sturm, Ruger & Co., Inc.
  "ABR"   # Arbor Realty Trust Inc.
)

years <- c(2017:2023)

stock_data_list <- purrr::map(
  tickers,
  get_yearly_yield,
  years
) |> 
  setNames(tickers)

Now, let’s visualize the yearly dividend yield for these stocks:

# Loading necessary packages
library(echarts4r)
library(tidyr)

chart_color_pallete <- c(
  "#212529",  # Main color
  "#A89F91",  # Warm gray
  "#1C3A70",  # Deep blue
  "#B0CCE1",  # Soft sky blue
  "#D1495B",  # Bright red (For contrast and pop)
  "#F9C74F",  # Golden yellow
  "#43AA8B",  # Teal green
  "#F8961E",  # Bright orange
  "#6A0572",  # Deep purple
  "#577590",  # Muted blue
  "#F9844A",  # Coral
  "#1982C4",  # Cerulean blue
  "#6B4226",  # Brown (earthy tone)
  "#3B3F45",  # Slightly lighter shade of the base
  "#0A0C0F"  # Darker, almost black, shade
)

range_years <- max(years) - min(years) - 1

# Transforming the data for plotting
stock_data <- stock_data_list |>
  bind_rows(.id = "ticker") |>
  mutate(year = as.factor(year)) |>
  # Keeping only highest mean yields
  group_by(ticker) |>
   mutate(
    yield_mean = mean(yield, na.rm = TRUE),
    total_years = length(unique(year))
  ) |>
  filter(yield_mean >= 8 && total_years >= range_years) |>
  ungroup() |>
  arrange(year)

stock_data |>
  group_by(ticker) |>
  e_charts(year) |>
  e_line(yield) |>
  e_y_axis(name = "Yield (%)") |>
  e_tooltip(trigger = "axis") |>
  e_color(chart_color_pallete) |>
  e_hide_grid_lines(which = "y")

Yearly Dividend Yield Analysis for Selected - Brazillian Stocks

Tickers extracted from this blog post:

tickers <- c(
  "CSNA3",  # CSN
  "SLCE3",  # SLC Agrícola
  "CPFE3",  # CPFL Energia
  "BBSE3",  # BB Seguridade
  "ENBR3",  # Energias do Brasil
  "JBSS3",  # JBS
  "BRAP4",  # Bradespar
  "BBDC4",  # Bradesco
  "USIM5",  # Usiminas
  "BBAS3",  # Banco do Brasil
  "VIVT3",  # Telefônica
  "EGIE3",  # Engie
  "CMIG4",  # Cemig
  "TAEE11", # Taesa
  "GOAU4",  # Gerdau Metalúrgica
  "ELET6",  # Eletrobras
  "BEEF3",  # Minerva
  "VALE3",  # Vale
  "SANB11", # Santander
  "GGBR4"   # Gerdau
)

years <- c(2017:2023)

stock_data_list <- purrr::map(
  paste0(tickers, ".SA"),
  get_yearly_yield,
  years
) |> 
  setNames(tickers)

Now, let’s visualize the yearly dividend yield for these stocks:

range_years <- max(years) - min(years) - 1

# Transforming the data for plotting
stock_data <- stock_data_list |>
  bind_rows(.id = "ticker") |>
  mutate(year = as.factor(year)) |>
  # Keeping only highest mean yields
  group_by(ticker) |>
  mutate(
    yield_mean = mean(yield, na.rm = TRUE),
    total_years = length(unique(year))
  ) |>
  filter(yield_mean >= 8 && total_years >= range_years) |>
  ungroup() |>
  arrange(year)

stock_data |>
  group_by(ticker) |>
  e_charts(year) |>
  e_line(yield) |>
  e_y_axis(name = "Yield (%)") |>
  e_tooltip(trigger = "axis") |>
  e_color(chart_color_pallete) |>
  e_hide_grid_lines(which = "y")

Conclusion

Using R, we have streamlined the process of fetching and analyzing yearly dividend data for stocks. This method allows investors and analysts to quickly evaluate the attractiveness of dividends over the years. By understanding the yearly yields, one can make better-informed decisions regarding their investments.

Further, the flexibility and power of R enable the expansion of this analysis. With a similar approach, one could:

  • Compare the dividend yield with other financial metrics for a more comprehensive stock evaluation.
  • Predict future dividend yields based on historical data using time-series forecasting techniques.
  • Incorporate external economic factors, such as interest rates or GDP growth, to understand their impact on dividend yields.

Remember, while dividends are a crucial aspect, they are just one part of a holistic analysis when evaluating stocks. Always consider a multitude of factors before making any investment decisions. Happy investing!