From b3bcf79f7cb3daa6d191debb59fd71c8055d5c9e Mon Sep 17 00:00:00 2001 From: gp1981 <45032495+gp1981@users.noreply.github.com> Date: Thu, 7 Dec 2023 23:26:58 +0100 Subject: [PATCH] bs_std function (WIP) Improved the mapping xlsx file. Comment in the code what to be fixed --- code/Functions/data_retrieval.R | 163 +++++++++++++--------------- code/Functions/utils.R | 13 ++- data/standardized_balancesheet.xlsx | Bin 15542 -> 16092 bytes 3 files changed, 85 insertions(+), 91 deletions(-) diff --git a/code/Functions/data_retrieval.R b/code/Functions/data_retrieval.R index 00b3cea..d11409d 100644 --- a/code/Functions/data_retrieval.R +++ b/code/Functions/data_retrieval.R @@ -85,115 +85,99 @@ bs_std <- function(df_Facts) { # Merge df_Facts with standardized_balancesheet df_std_BS <- df_Facts %>% left_join(standardized_balancesheet, by = "label") %>% - select(standardized_balancesheet_label,everything(),-df_Fact_Description,) + select(standardized_balancesheet_label, everything(), -df_Fact_Description) # Filter out records not associated with standardized_balancesheet to create the mapping with df_Facts df_std_BS_map <- df_std_BS %>% filter(!is.na(standardized_balancesheet_label)) %>% - select(standardized_balancesheet_label,label,description) %>% + select(standardized_balancesheet_label, label, description) %>% distinct() # Filter out records not associated with standardized_balancesheet to create the pivot df_std_BS <- df_std_BS %>% filter(!is.na(standardized_balancesheet_label)) %>% - select(standardized_balancesheet_label,end,val,fy,fp,form,filed,start) - + select(standardized_balancesheet_label, end, val, fy, fp, form, filed, start) # Pivot the data to the desired structure - # This function introduces a grouping by label, fy and fp and adds a logical column (has_form_A and has_form) to identify whether there is a row with /A and a row without /A for the same fy and fp. Rows without /A and with a corresponding row with /A will be filtered out. - df_std_BS_test <- df_std_BS %>% - filter(!is.na(standardized_balancesheet_label)) %>% - mutate(end = ymd(end), filed = ymd(filed)) %>% # convert to date format - group_by(standardized_balancesheet_label, end) %>% - filter(filed == max(filed)) %>% # filter rows with the most recent filing date - ungroup() %>% - select(standardized_balancesheet_label, end, val, fy, fp, form, filed, start) %>% + df_std_BS <- df_std_BS %>% pivot_wider( names_from = standardized_balancesheet_label, values_from = val ) %>% arrange(desc(end)) - # <---- NEED TO CHECK STILL DUPLICATED ROW WITH 1 VARIABLE see 2020-12-31 NA ----> - # Perform the calculation for additional records in the balancesheet + + # <<---THIS BELOW TO BE MOVED UP BEFORE PITVOR_WIDER --->>> + # Identify and retain the row with the greatest value for "Preferred Stock" and filter out the rest df_std_BS <- df_std_BS %>% - mutate( - 'Total Long Term Assets' = ifelse( - !is.na('Total Long Term Assets'), - 'Total Assets' - 'Total Current Assets', - NA_real_ - ) - ) - - , - 'Other Current Assets' = ifelse( - !is.na('Total Current Assets') & - !is.na('Cash & Cash Equivalent') & - !is.na('Marketable Securities, Current') & - !is.na('Total Accounts Receivable') & - !is.na('Total Inventories'), - 'Total Current Assets' - - ('Cash & Cash Equivalent' + - 'Marketable Securities, Current' + - 'Total Accounts Receivable' + - 'Total Inventories'), - NA_real_ - ) + filter(!(standardized_balancesheet_label == "Preferred Stock" & duplicated(fy, fromLast = TRUE))) - , - 'Other Long Term Assets' = ifelse( - !is.na('Total Long Term Assets') & - !is.na('Marketable Securities, Non Current') & - !is.na('Property, Plant and Equipment') & - !is.na('Intangible Assets (excl. goodwill)') & - !is.na('Goodwill'), - 'Total Long Term Assets' - - ('Marketable Securities, Non Current' + - 'Property, Plant and Equipment' + - 'Intangible Assets (excl. goodwill)' + - 'Goodwill'), - NA_real_ + # Calculate values based on specified formulas + df_std_BS <- df_std_BS %>% + mutate( + `Total Current Assets` = ifelse( + is.na(`Total Current Assets`) | `Total Current Assets` == 0, + `Total Assets` - `Total Long Term Assets`, + `Total Current Assets` + ), + `Other Current Assets` = ifelse( + is.na(`Other Current Assets`) | `Other Current Assets` == 0, + `Total Current Assets` - ( + `Cash & Cash Equivalent` + + `Marketable Securities, Current` + + `Total Accounts Receivable` + + `Total Inventories` + ), + `Other Current Assets` + ), + `Total Long Term Assets` = ifelse( + is.na(`Total Long Term Assets`) | `Total Long Term Assets` == 0, + `Total Assets` - `Total Current Assets`, + `Total Long Term Assets` ), - 'Other Current Liabilities' = ifelse( - !is.na('Total Current Liabilities') & - !is.na('Accounts Payable') & - !is.na('Tax Payable') & - !is.na('Commercial papers') & - !is.na('Short-Term Debt') & - !is.na('Operating Lease, Liability, Current'), - 'Total Current Liabilities' - - ('Accounts Payable' + 'Tax Payable' + - 'Commercial papers' + - 'Short-Term Debt' + - 'Operating Lease, Liability, Current'), - NA_real_ + `Other Non Current Assets` = ifelse( + is.na(`Other Non Current Assets`) | `Other Non Current Assets` == 0, + `Total Long Term Assets` - ( + `Marketable Securities, Non Current` + + `Property, Plant and Equipment` + + `Intangible Assets (excl. goodwill)` + + `Goodwill` + ), + `Other Non Current Assets` ), - 'Other Long Term Liabilities' = ifelse( - !is.na('Total Long Term Liabilities') & - !is.na('Long Term Debts') & - !is.na('Operating Lease, Liability, Non Current') & - !is.na('Finance Lease, Liability, Non Current'), - 'Total Long Term Liabilities' - - ('Long Term Debts' + - 'Operating Lease, Liability, Non Current' + - 'Finance Lease, Liability, Non Current'), - NA_real_ + `Total Current Liabilities` = ifelse( + is.na(`Total Current Liabilities`) | `Total Current Liabilities` == 0, + `Liabilities` - `Liabilities, Non Current`, + `Total Current Liabilities` ), - 'Other Company Stockholders Equity' = ifelse( - !is.na('Total Company Stockholders Equity') & - !is.na('Common Stock & Additional paid-in capital') & - !is.na('Common Stock, Value, Issued') & - !is.na('Additional Paid in Capital') & - !is.na('Preferred Stock') & - !is.na('Retained Earnings') & - !is.na('Accumulated other comprehensive income (loss)'), - 'Total Company Stockholders Equity' - - ('Common Stock & Additional paid-in capital' + - 'Common Stock, Value, Issued' + - 'Additional Paid in Capital' + - 'Preferred Stock' + - 'Retained Earnings' + - 'Accumulated other comprehensive income (loss)'), - NA_real_ + `Other Current Liabilities` = ifelse( + is.na(`Other Current Liabilities`) | `Other Current Liabilities` == 0, + `Total Current Liabilities` - ( + `Accounts Payable, Current` + `Taxes Payable, Current` + + `Commercial Paper` + `Long Term Debt, Current Maturities` + + `Operating Lease, Liability, Current` + `Finance Lease, Liability, Current` + ), + `Other Current Liabilities` + ), + `Total Long Term Liabilities` = ifelse( + is.na(`Total Long Term Liabilities`) | `Total Long Term Liabilities` == 0, + `Total Liabilities` - `Total Current Liabilities`, + `Total Long Term Liabilities` + ), + `Other Long Term Liabilities` = ifelse( + is.na(`Other Long Term Liabilities`) | `Other Long Term Liabilities` == 0, + `Total Long Term Liabilities` - ( + `Long Term Debts` + `Operating Lease, Liability, Non Current` + + `Finance Lease, Liability, Non Current` + ), + `Other Long Term Liabilities` + ), + `Other Stockholders Equity` = ifelse( + is.na(`Other Stockholders Equity`) | `Other Stockholders Equity` == 0, + `Total Company Stockholders Equity` - ( + `Common Stock` + `Additional Paid in Capital` + `Preferred Stock` + + `Retained Earnings` + `Accumulated other comprehensive income (loss)` + ), + `Other Stockholders Equity` ) ) @@ -206,7 +190,8 @@ bs_std <- function(df_Facts) { # Reorder columns for better readability df_std_BS <- df_std_BS[, c("end", "fy", "fp", "form", column_order)] - return(df_std_BS) + return(df_std_BS) } + diff --git a/code/Functions/utils.R b/code/Functions/utils.R index 5e143c2..0ccd02a 100644 --- a/code/Functions/utils.R +++ b/code/Functions/utils.R @@ -4,6 +4,15 @@ # Import required libraries library(tidyverse) +library(purrr) - - +# Function to unnest a list +unnest_list <- function(x) { + purrr::map(x, ~{ + if (is.list(.x)) { + unnest_list(.x) + } else { + .x + } + }) +} diff --git a/data/standardized_balancesheet.xlsx b/data/standardized_balancesheet.xlsx index a1ee9f17c6fb444302cfaa6a0b195b73b25dffdb..d07e615b912ee1ee958045d0cdb75fb3ba155822 100644 GIT binary patch delta 9049 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 MA(ZeS$bZ291wg1rZ~y=R delta 8439 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