SkillAgentSearch skills...

Finstr

:chart_with_upwards_trend: Financial statements in R

Install / Use

/learn @bergant/Finstr
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

finstr

The purpose of finstr package is to create an environment for reproducible financial statement analysis. The package will not cover specific types of analysis (except in examples and package vignettes) but will provide a domain language to write them. With other functions in basic R and existing R packages it anables users to store, share, reuse and reproduce the results of their analitic work.

For now it is offering:

1. Data structure for financial statements

  • Reading from data parsed with XBRL package
  • Statements in tidy format with accounting taxonomy concepts as columns
  • Encapsulates calculation hierarchy of variables
  • Default printing in transposed format and with visible hierarchy

2. Statement calculation validation

  • Calculation of higher order elements
  • Check if calculated values match original values

3. Merge statements

  • Merge different periods of equal statement type
  • Merge statements of a different type

4. Calculate and reveal

  • Custom financial ratio calculations definitions
  • Exposing data by rearranging the statament hierarchy
  • Time lagged difference

Installation

To install finstr from github use install_github from devtools package:

library(devtools)
install_github("bergant/finstr")

Get data

Use XBRL package to parse XBRL files. For example:

library(XBRL)
# parse XBRL (Apple 10-K report)
xbrl_url2014 <- "https://www.sec.gov/Archives/edgar/data/320193/000119312514383437/aapl-20140927.xml"
xbrl_url2013 <- 
  "https://www.sec.gov/Archives/edgar/data/320193/000119312513416534/aapl-20130928.xml"
old_o <- options(stringsAsFactors = FALSE)
xbrl_data_aapl2014 <- xbrlDoAll(xbrl_url2014)
xbrl_data_aapl2013 <- xbrlDoAll(xbrl_url2013)
options(old_o)

Prepare statements

With xbrl_get_statements convert XBRL data to statements object.

library(finstr)

st2013 <- xbrl_get_statements(xbrl_data_aapl2013)
st2014 <- xbrl_get_statements(xbrl_data_aapl2014)
st2014
#> Financial statements repository
#>                                              From         To Rows Columns
#> StatementOfIncome                      2012-09-29 2014-09-27    3      15
#> StatementOfOtherComprehensiveIncome    2012-09-29 2014-09-27    3      14
#> StatementOfFinancialPositionClassified 2013-09-28 2014-09-27    2      33
#> StatementOfCashFlowsIndirect           2012-09-29 2014-09-27    3      33

Statements object is a list of several statement objects (ballance sheets, income and cash flow statements).

To get a single statement use statements object as a regular R list:

balance_sheet2013 <- st2013$StatementOfFinancialPositionClassified
balance_sheet2014 <- st2014$StatementOfFinancialPositionClassified
income2013 <- st2013$StatementOfIncome
income2014 <- st2014$StatementOfIncome
balance_sheet2014
#> Financial statement: 2 observations from 2013-09-28 to 2014-09-27 
#>  Element                                             2014-09-27 2013-09-28
#>  Assets =                                            231839     207000    
#>  + AssetsCurrent =                                    68531      73286    
#>    + CashAndCashEquivalentsAtCarryingValue            13844      14259    
#>    + AvailableForSaleSecuritiesCurrent                11233      26287    
#>    + AccountsReceivableNetCurrent                     17460      13102    
#>    + InventoryNet                                      2111       1764    
#>    + DeferredTaxAssetsNetCurrent                       4318       3453    
#>    + NontradeReceivablesCurrent                        9759       7539    
#>    + OtherAssetsCurrent                                9806       6882    
#>  + AvailableForSaleSecuritiesNoncurrent              130162     106215    
#>  + PropertyPlantAndEquipmentNet                       20624      16597    
#>  + Goodwill                                            4616       1577    
#>  + IntangibleAssetsNetExcludingGoodwill                4142       4179    
#>  + OtherAssetsNoncurrent                               3764       5146    
#>  LiabilitiesAndStockholdersEquity =                  231839     207000    
#>  + Liabilities =                                     120292      83451    
#>    + LiabilitiesCurrent =                             63448      43658    
#>      + AccountsPayableCurrent                         30196      22367    
#>      + AccruedLiabilitiesCurrent                      18453      13856    
#>      + DeferredRevenueCurrent                          8491       7435    
#>      + CommercialPaper                                 6308          0    
#>    + DeferredRevenueNoncurrent                         3031       2625    
#>    + LongTermDebt                                     28987      16960    
#>    + OtherLiabilitiesNoncurrent                       24826      20208    
#>  + CommitmentsAndContingencies                            0          0    
#>  + StockholdersEquity =                              111547     123549    
#>    + CommonStocksIncludingAdditionalPaidInCapital     23313      19764    
#>    + RetainedEarningsAccumulatedDeficit               87152     104256    
#>    + AccumulatedOtherComprehensiveIncomeLossNetOfTax   1082       -471
tail(income2014, 2)
#> Financial statement: 2 observations from 2013-09-28 to 2014-09-27 
#>  Element                                          2014-09-27 2013-09-28
#>  NetIncomeLoss =                                   39510      37037    
#>  + IncomeLossFromContinuingOperationsBefore... =   53483      50155    
#>    + OperatingIncomeLoss =                         52503      48999    
#>      + GrossProfit =                               70537      64304    
#>        + SalesRevenueNet                          182795     170910    
#>        - CostOfGoodsAndServicesSold               112258     106606    
#>      - OperatingExpenses =                         18034      15305    
#>        + ResearchAndDevelopmentExpense              6041       4475    
#>        + SellingGeneralAndAdministrativeExpense    11993      10830    
#>    + NonoperatingIncomeExpense                       980       1156    
#>  - IncomeTaxExpenseBenefit                         13973      13118

Validate statement calculation hierarchy

Recalculate higher order concepts from basic values and check for errors.

check <- check_statement(balance_sheet2014)
check
#> Number of errors:  0 
#> Number of elements in errors:  0

In case of error the numbers with errors will be presented along with elements:

check_statement(
  within(balance_sheet2014, InventoryNet <- InventoryNet * 2)
)
#> Number of errors:  2 
#> Number of elements in errors:  1 
#> 
#> Element: AssetsCurrent  =  + CashAndCashEquivalentsAtCarryingValue + AvailableForSaleSecuritiesCurrent + AccountsReceivableNetCurrent + InventoryNet + DeferredTaxAssetsNetCurrent + NontradeReceivablesCurrent + OtherAssetsCurrent 
#>         date   original calculated      error
#> 3 2013-09-28 7.3286e+10 7.5050e+10 -1.764e+09
#> 4 2014-09-27 6.8531e+10 7.0642e+10 -2.111e+09

Validation returns all calculation results in a readable data frame. Lets check only operating income from income statement:

check <- check_statement(income2014, element_id = "OperatingIncomeLoss")
check
#> Number of errors:  0 
#> Number of elements in errors:  0
check$expression[1]
#> [1] "+ GrossProfit - OperatingExpenses"
check$calculated / 10^6
#> [1] 55241 48999 52503

Merge statements from different periods

Use merge function to create single financial statement data from two statements.

balance_sheet <- merge( balance_sheet2013, balance_sheet2014 )

The structure of merged balance sheets may differ if XBRL taxonomy changes. Function merge takes care of it by expanding the elements hierarchy to fit both statements. The values of any missing elements in different periods is set to 0.

To merge all statements from statements object use merge on statements objects:

# merge all statements
st_all <- merge( st2013, st2014 )
# check if balance sheets are merged:
balance_sheet <- st_all$StatementOfFinancialPositionClassified
balance_sheet$endDate
#> [1] "2012-09-29" "2013-09-28" "2014-09-27"

Merge different types of statements

If there are no matching elements between the two statements merge joins statements by matching their periods. For some financial ratio calculations the combined statement may be a better starting point.

  merge.statement(
    st_all$StatementOfFinancialPositionClassified, 
    st_all$StatementOfIncome )

Calculate financial ratios

Statement object (in our case balance_sheet) is also a data frame object with statement elements as columns and time periods as rows. It is possible then to use statement as a data frame.

Lets calculate current ratio which is defined by

$$ Current Ratio = \frac{Current Assets}{Current Liabilities} $$

With dplyr package we can use mutate, select or transmute functions:

library(dplyr)

balance_sheet %>% transmute(
  date = endDate, 
  CurrentRatio = AssetsCurrent / LiabilitiesCurrent
)
#>         date CurrentRatio
#> 1 2012-09-29     1.495849
#> 2 2013-09-28     1.678639
#> 3 2014-09-27     1.080113

By using finstr::calculate function we can achieve the same result but don't have to handle the date field and there is a rounding parameter. Lets calculate for example two ratios:


balance_sheet %>% calculate( digits = 2,
  
    Current_Ratio = AssetsCurrent / LiabilitiesCurrent,
    
    Quick_Ratio =  
      ( CashAndCashEquivalentsAtCarryingValue + 
          AvailableForSaleSecuritiesCurrent +
          AccountsReceivableNetCurrent
        ) / LiabilitiesCurrent
    
)
#>         date Current_Ratio Quick_Ratio
#> 1 201

Related Skills

View on GitHub
GitHub Stars255
CategoryDevelopment
Updated2mo ago
Forks69

Languages

R

Security Score

85/100

Audited on Jan 22, 2026

No findings