esovetkin / r-ledger

R package for importing data from plain text accounting files

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ledger

CRAN Status Badge

Travis-CI Build Status

AppVeyor Build Status

Coverage Status

RStudio CRAN mirror downloads

Project Status: Active – The project has reached a stable, usable state and is being actively developed.

ledger is an R package to import data from plain text accounting software like Ledger, HLedger, and Beancount into an R data frame for convenient analysis, plotting, and export.

Right now it supports reading in the register from ledger, hledger, and beancount files.

Installation

This package depends on R and the R packages dplyr, rio, rlang, and tidyr.

To install the development version of the ledger package (and its R package dependencies) use the install_github function from the devtools package in R:

if(!require("devtools")) { install.packages("devtools") }
devtools::install_github("trevorld/r-ledger")

This package also has some system dependencies depending on which plaintext accounting files you wish to read to be able to read in:

ledger
  • ledger (>= 3.1) OR for a subset of files hledger (>= 1.4)
hledger
  • hledger (>= 1.4) OR for a subset of files ledger (>= 3.1)
beancount

To install hledger and beancount run:

$ stack install --resolver=lts hledger-lib-1.9 hledger-1.9
$ pip3 install beancount

Several pre-compiled Ledger binaries are available (often found in several open source repos).

To run the unit tests you'll also need the suggested R package testthat.

Examples

The main function of this package is register which reads in the register of a plaintext accounting file. This package also exports S3 methods so one can use rio::import to read in a register and a net_worth convenience function.

register

Here is an example reading in the example beancount file generated by bean-example:

> library("ledger")
> example_beancount_file <- tempfile(fileext = ".beancount")
> system(paste("bean-example -o", example_beancount_file), ignore.stderr=TRUE)
> df <- register(example_beancount_file)
> head(df)
        date mark                payee                          description
1 2016-01-01    *                 <NA> Opening Balance for checking account
2 2016-01-01    *                 <NA> Opening Balance for checking account
3 2016-01-01    *                 <NA>   Allowed contributions for one year
4 2016-01-01    *                 <NA>   Allowed contributions for one year
5 2016-01-03    * RiverBank Properties                      Paying the rent
6 2016-01-03    * RiverBank Properties                      Paying the rent
                       account    amount commodity historical_cost hc_commodity
1      Assets:US:BofA:Checking   4241.86       USD         4241.86          USD
2      Equity:Opening-Balances  -4241.86       USD        -4241.86          USD
3 Income:US:Federal:PreTax401k -18000.00    IRAUSD       -18000.00       IRAUSD
4 Assets:US:Federal:PreTax401k  18000.00    IRAUSD        18000.00       IRAUSD
5      Assets:US:BofA:Checking  -2400.00       USD        -2400.00          USD
6           Expenses:Home:Rent   2400.00       USD         2400.00          USD
  market_value mv_commodity
1      4241.86          USD
2     -4241.86          USD
3    -18000.00       IRAUSD
4     18000.00       IRAUSD
5     -2400.00          USD
6      2400.00          USD

Here is an example of using the flags argument (in this case passed to hledger register) to filter on any of the tags starting with #trip in the example beancount file:

> df <- register(example_beancount_file, flags="tag:Tag=#trip")
> head(df)
        date mark payee description                    account amount commodity
1 2016-09-21    *    NA          NA Liabilities:US:Chase:Slate -14.84       USD
2 2016-09-21    *    NA          NA   Expenses:Food:Restaurant  14.84       USD
3 2016-09-21    *    NA          NA Liabilities:US:Chase:Slate  -4.81       USD
4 2016-09-21    *    NA          NA      Expenses:Food:Alcohol   4.81       USD
5 2016-09-22    *    NA          NA Liabilities:US:Chase:Slate -29.22       USD
6 2016-09-22    *    NA          NA   Expenses:Food:Restaurant  29.22       USD
  historical_cost hc_commodity market_value mv_commodity
1          -14.84          USD       -14.84          USD
2           14.84          USD        14.84          USD
3           -4.81          USD        -4.81          USD
4            4.81          USD         4.81          USD
5          -29.22          USD       -29.22          USD
6           29.22          USD        29.22          USD
> suppressPackageStartupMessages(library("dplyr"))
> dplyr::filter(df, grepl("Expenses", account)) %>% group_by(account) %>% 
+ summarise(trip_total = sum(amount))
# A tibble: 3 x 2
                   account trip_total
                     <chr>      <dbl>
1    Expenses:Food:Alcohol      46.71
2     Expenses:Food:Coffee      52.00
3 Expenses:Food:Restaurant    1353.95

Note: There is currently a bug in bean-report that leads us to lose the payee and description for any transactions that uses a #tag (or ^link) tag in a beancount file.

Using rio::import and rio::convert

If one has loaded in the ledger package one can also use rio::import to read in the register:

> df2 <- rio::import(example_beancount_file)
> all.equal(df, df2)
[1] TRUE

This allows one to use rio::convert to easily convert plaintext accounting files to other file formats such as a csv file:

$ bean-example -o example.beancount
$ Rscript --default-packages=ledger,rio -e 'convert("example.beancount", "example.csv")'

net_worth

Some examples of using the net_worth function:

> example_ledger_file <- system.file("extdata", "example.ledger", package = "ledger") 
> net_worth(example_ledger_file)
# A tibble: 1 x 6
        date commodity net_worth assets liabilities revalued
      <date>     <chr>     <dbl>  <dbl>       <dbl>    <dbl>
1 2018-06-11       USD   8125.39   7646     -520.61     1000
> example_hledger_file <- system.file("extdata", "example.hledger", package = "ledger") 
> net_worth(example_hledger_file, c("2016-01-01", "2017-01-01", "2018-01-01"))
# A tibble: 3 x 5
        date commodity net_worth assets liabilities
      <date>     <chr>     <dbl>  <dbl>       <dbl>
1 2016-01-01       USD   5000.00   5000        0.00
2 2017-01-01       USD   4361.39   4882     -520.61
3 2018-01-01       USD   6743.39   7264     -520.61
> example_beancount_file <- tempfile(fileext = ".beancount")
> system(paste("bean-example -o", example_beancount_file), ignore.stderr=TRUE)
> ledger::net_worth(example_beancount_file)
# A tibble: 4 x 5
        date commodity net_worth   assets liabilities
      <date>     <chr>     <dbl>    <dbl>       <dbl>
1 2018-06-11    IRAUSD    4100.0   4100.0        0.00
2 2018-06-11       USD  104011.7 107221.6    -3209.91
3 2018-06-11     VACHR    -128.0   -128.0        0.00
4 2018-06-11      <NA>       0.0      0.0        0.00
> system(paste("bean-report", example_beancount_file, "networth"))
Currency   Net Worth
--------  ----------
USD       104,011.74
--------  ----------

Note: There is currently a bug in hledger register -f file.hledger -o file.csv where commodities are missing when the amount is zero.

About

R package for importing data from plain text accounting files

License:Other


Languages

Language:R 93.2%Language:Shell 4.1%Language:Ruby 2.6%