Giter VIP home page Giter VIP logo

tidycells's Introduction

tidycells

Read Tabular Data from Diverse Sources and Easily Make Them Tidy

CRAN status CRAN checks Travis build status AppVeyor build status R-hub checks Project Status: Suspended – Initial development has started, but there has not yet been a stable, usable release; work has been stopped for the time being but the author(s) intend on resuming work. Codecov Coverage Status Coveralls Coverage Status Lifecycle Dependency status license See DevNotes

CircleCI build status R build status

Author

Indranil Gayen

TL;DR

Given a file_name which is a path of a file that contains table(s). Run this read_cells() in the R-console to see whether support is present for the file type. If support is present, just run

read_cells(file_name)

Note

  • Just start with a small file, as heuristic-algorithm are not well-optimized (yet).
  • If the target table has numerical values as data and text as their attribute (identifier of the data elements), straight forward method is sufficient in the majority of situations. Otherwise, you may need to utilize other functions.

A Word of Warning :

Many functions in this package are heuristic-algorithm based. Thus, outcomes may be unexpected. I recommend you to try read_cells on the target file. If the outcome is what you are expecting, it is fine. If not try again with read_cells(file_name, at_level = "compose"). If after that also the output is not as expected then other functions are required to be used. At that time start again with read_cells(file_name, at_level = "make_cells") and proceed to further functions.

Introduction

The package provides utilities to read, cells from complex tabular data and heuristic detection based ‘structural assignment’ of those cells to a columnar or tidy format.

Read functionality has the ability to read (in a unified manner) structured, partially structured or unstructured tabular data (usually spreadsheets for public data dissemination and aimed for common human understanding) from various types of documents. The tabular information is read as cells. The ‘structure assignment’ functionality has both supervised and unsupervised way of assigning cells data to columnar/tidy format. Multiple disconnected blocks of tables in a single sheet are also handled appropriately.

These tools are suitable for unattended conversation of (maybe a pile of) messy tables (like government data) into a consumable format(usable for further analysis and data wrangling).

Installation

Install the CRAN version:

install.packages("tidycells")

To install the development version from GitHub you’ll need remotes package in R (comes with devtools). Assuming you have remotes you can install this package in R with the following command:

# devtools::install_github is actually remotes::install_github
remotes::install_github("r-rudra/tidycells")

To start with tidycells, I invite you to see vignette("tidycells-intro") or check out tidycells-website (to see vignette you need to install the package with vignette. That can be done in above command (remotes::install_github) by specifying build_vignettes = TRUE. Note that, it might be time consuming. CRAN version comes with prebuilt-vignette).

Quick Overview

Let’s take a quick look at an example data as given in

system.file("extdata", "marks.xlsx", package = "tidycells", mustWork = TRUE)

The data looks like (in excel)

Let’s try tidycells functions in this data

Read at once

# you should have tidyxl installed
system.file("extdata", "marks.xlsx", package = "tidycells", mustWork = TRUE) %>% 
  read_cells()
collated_1 collated_2 collated_3 collated_4 collated_5 table_tag value
Score Male School A Student Name Utsyo Roy Sheet1 95
Score Male School A Student Name Nakshatra Gayen Sheet1 99
Score Female School A Student Name Titas Gupta Sheet1 89
Score Female School A Student Name Ujjaini Gayen Sheet1 100
Score Male School B Student Indranil Gayen Sheet1 70
Score Male School B Student S Gayen Sheet1 75
Score Female School B Student Sarmistha Senapati Sheet1 81
Score Female School B Student Shtuti Roy Sheet1 90
Score Male School C Name I Roy Sheet1 50
Score Male School C Name S Ghosh Sheet1 59
Score Female School C Name S Senapati Sheet1 61
Score Female School C Name U Gupta Sheet1 38

The function read_cells is a set of ordered operations connected together. The flowchart of read_cells:

Let’s understand step by step procedures followed by read_cells.

# if you have tidyxl installed
d <- system.file("extdata", "marks.xlsx", package = "tidycells", mustWork = TRUE) %>% 
  read_cells(at_level = "make_cells") %>% 
  .[[1]]

Or

# or you may do
d <- system.file("extdata", "marks_cells.rds", package = "tidycells", mustWork = TRUE) %>% 
  readRDS()

Then

d <- numeric_values_classifier(d)
da <- analyze_cells(d)

After this you need to run compose_cells (with argument print_attribute_overview = TRUE)

dc <- compose_cells(da, print_attribute_overview = TRUE)

If you want a well-aligned columns then you may like to do

# bit tricky and tedious unless you do print_attribute_overview = TRUE in above line
dcfine <- dc %>% 
  dplyr::mutate(name = dplyr::case_when(
    data_block == 1 ~ major_row_left_2_1,
    data_block == 2 ~ major_col_bottom_1_1,
    data_block == 3 ~ major_row_left_1_1
  ),
  sex = dplyr::case_when(
    data_block == 1 ~ major_row_left_1_1,
    data_block == 2 ~ major_col_bottom_2_1,
    data_block == 3 ~ minor_row_right_1_1
  ),
  school = dplyr::case_when(
    data_block == 1 ~ minor_col_top_1_1,
    data_block == 2 ~ minor_corner_topLeft_1_1,
    data_block == 3 ~ minor_col_top_1_1
  )) %>% 
  dplyr::select(school,sex, name, value)

head(dcfine) looks like

school sex name value
School A Male Utsyo Roy 95
School A Male Nakshatra Gayen 99
School A Female Titas Gupta 89
School A Female Ujjaini Gayen 100
School B Male Indranil Gayen 70
School B Male S Gayen 75

This is still not good right! You had to manually pick some weird column-names and spent some time and energy (when it was evident from data which columns should be aligned with whom).

The collate_columns functions does exactly this for you. So instead of manually picking column-names after compose cells you can simply run

# collate_columns(dc) should be same with 
# direct read_cells() result except table_tag column
collate_columns(dc) %>% 
  head()
collated_1 collated_2 collated_3 collated_4 collated_5 value
Score Male School A Student Name Utsyo Roy 95
Score Male School A Student Name Nakshatra Gayen 99
Score Female School A Student Name Titas Gupta 89
Score Female School A Student Name Ujjaini Gayen 100
Score Male School B Student Indranil Gayen 70
Score Male School B Student S Gayen 75

Looks like staged example! Yes, you are right this is not always perfect (same is true for analyze_cells also). However, if the data is somehow helpful in demystifying underlying columns structure (like this one), then this will be useful.

These functions read_cells (all functionalities combined), analyze_cells, collate_columns are here to ease your pain in data wrangling and reading from various sources. It may not be full-proof solution to all types of tabular data. It is always recommended to perform these tasks manually whenever expected results are not coming.

Plots and Interactive Modules

The package provides ggplot based plots and shiny based interactive visualisations for understanding how the heuristic is functioning and also provides object (like cell-df or cell-analysis) editing capabilities.

The shiny package is required for interactive modules. Most of the features are self-explanatory and guided.

Check out interactive documentation of any of these functions listed below. All of these functions are available as RStudio Addins.

Here are screenshots of each interactive widgets.

  1. Plot tune (part of all modules)
  2. visual_crop() for data crop and deletion of sections

  1. visual_va_classify() for interactive VA classification
  2. visual_data_block_inspection() this shows how the heuristic has performed the analysis after analyze_cells

  1. visual_orientation_modification() for modification to heuristic based results
  2. visual_traceback() this is for observing how the original data is composed to form the final output. (compose_cells is called internally)

For each of these modules, there is a dynamic plot option available from plotly. If you have that package, the corresponding tab will be activated. Since all of these modules are entirely optional the dependency is kept at tidycells ‘suggests’ level only.

Reference and Related Projects

  • tidyxl: Read Untidy Excel Files: Imports non-tabular from Excel files into R. Exposes cell content, position and formatting in a tidy structure for further manipulation. Tokenizes Excel formulas. Supports ‘.xlsx’ and ‘.xlsm’ via the embedded ‘RapidXML’ C++ library http://rapidxml.sourceforge.net. Does not support ‘.xlsb’ or ‘.xls’.
  • unpivotr: Unpivot Complex and Irregular Data Layouts Tools for converting data from complex or irregular layouts to a columnar structure. For example, tables with multilevel column or row headers, or spreadsheets. Header and data cells are selected by their contents and position, as well as formatting and comments where available, and are associated with one other by their proximity in given directions. Functions for data frames and HTML tables are provided. Major parts of the package right now fully depend on unpivotr. The tidycells package would have never existed without this wonderful package from Duncan Garmonsway.
  • The rsheets project: It hosts several R packages (few of them are in CRAN already) which are in the early stages of importing spreadsheets from Excel and Google Sheets into R. Specifically, have a look at these projects which seems closely related to these projects : jailbreaker, rexcel (README of this project has a wonderful reference for excel integration with R).
  • readabs: Download and Tidy Time Series Data from the Australian Bureau of Statistics The readabs package helps you easily download, import, and tidy time series data from the Australian Bureau of Statistics from within R. This saves you time manually downloading and tediously tidying time series data and allows you to spend more time on your analysis.
  • ezpickr: Easy Data Import Using GUI File Picker and Seamless Communication Between an Excel and R Gives ability for choosing any rectangular data file using interactive GUI dialog box, and seamlessly manipulating tidy data between an ‘Excel’ window and R session.
  • The tidyABS package: The tidyABS package converts ABS excel tables to tidy data frames. It uses rules-of-thumb to determine the structure of excel tables, however it sometimes requires pointers from the user. This package is in early development.
  • The hypoparsr package: This package takes a different approach to CSV parsing by creating different parsing hypotheses for a given file and ranking them based on data quality features.

Acknowledgement

This package incomplete without following packages (apart from the unpivotr which is the core package on which tidycells depends largely, as mentioned above). Each of these packages are in suggests fields of tidycells. (The read_cells basically, performs unification on several functions from various packages to give you support for different file types. These are listed below.)

  • readr: for csv (in melted format)
  • readxl: for reading xls (if xlsx is present by default xlsx will be used for xls)
  • xlsx: for reading xls (also it has capabilities to read xlsx)
  • tidyxl: really fast library for reading xlsx
  • docxtractr : for docx and doc (it has a system level dependency now)
  • tabulizer : for pdf
  • XML : for html/xml type files
  • stringdist : for enhanced string matching in tidycells::collate_columns

tidycells's People

Contributors

bedantaguru avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

tidycells's Issues

Create Example Data on which read_cells works (as expected)

The algorithm currently working on certain types of data. Definitely, It is yet not rendering the expected output on several well-known data. Add support for those.

As of now supported. (CRAN V0.2.1)

NOT working on it due to personal reasons.

Due to personal reasons (completely unavoidable) I'm not working on it for time being.

Hopefully, I'll be able to smile again and will gather enough strength mentally to start working on it again.

Absolutely sorry for such situation.

Detect screen resolution for better widget preview

This is for

viewer <- dialogViewer(title,

This may be implemented later if required.

Thanks to this SO

Following code works well :

library(rJava)
.jinit()
toolkit <- J("java.awt.Toolkit")
default_toolkit <- .jrcall(toolkit, "getDefaultToolkit")
dim <- .jrcall(default_toolkit, "getScreenSize")
height <- .jcall(dim, "D", "getHeight")
width <- .jcall(dim, "D", "getWidth")

Planned activities for 0.3

These are the planned activity for 0.3.0
These are in progress in nightly
Few of these may be dropped (as all of these are experimental)

  • Complete Heuristic maturation phase 1 : complete #5
  • Introduce grammar
  • %<^% kind of symbols for NNE etc.
  • Add shinytest prototype as described in #13
  • Compatibility of cell traceback with external operations (like {unpivotr} etc)
  • Multi routes tests
  • Optional packages availability based test
  • Mark cell-analysis for remodelling into a state (maybe in later version)
  • {DT} based table plots - check #16
  • reveal.js – Presentation for various topics
  • {pkgdown} tweaks [like all tables to DT etc]
  • Explore Github Actions as guided in this. Also check #18
  • Fix all issues tagged as bug like ( #20 )

Safe dependency framework needs to be implemented

  • As of 0.2.x, I'm doing this Adhoc basis.
  • I need to do in for 0.3.x

All dependency checks should route through is_available and a functionalities database to be maintained for checking whether a specific functionality is working.

Package description

Please be more specific than "diverse sources" when describing the package. Suggest "diverse sources such as Excel, Word, XML and HTML" rather than just "diverse sources" or add the others if there are others. I couldn't initially figure out if it applied to my problem without reading more than I thought was reasonable.

Link and Relate with other Big Projects

Numerous attempt made earlier by many other developers. Few projects are really groundbreaking. These may be not in the domain of #rstats but worth connecting with these projects and check where tidycells stands.

Check out these projects

Add self-test feature to test file-readability on the fly based on user demand

Already added a prototype/working version in cae10c0

This is to test read functions capabilities for various file types.

A broader framework can be adopted here to make almost all tests available to the user through appropriate channels.

The idea is that a test will be conditional when there is a heavy dependency on the system or third-party library. But user should have an option to run these tests for debugging/knowing machine issues. A guide also can be made for raising the issue in Github for the same.

This can be implemented by adopting tests that were already written.

As of now, a separate function is written for a test.

possible_to_support_real_file_type_checks <- function() {

Clean up class assignments

make sure primitive types and S3 inheritance is maintained correctly.

  • This is done loosely in 0.2.x but need
  • to do more robustly in 0.3.x

Create new Function read_it for reading data without heuristic detection

Modify read_cells to optionally opt for "heuristic detection" and "structural assignment". The proposed function read_it (should be a wrapper for read_cells with appropriate arguments) can do the following things

  • Read data as it is. Required for already structured data.
  • Try to find out whether reading as it is is ok or not.
  • Try to combine similar tables in a document based on headers.
  • Try to alert the user about what else to be done in order to read the data from the selected file. If the file type is not supported or any additional package is required to inspect.
  • Detect column type after (on-demand basis) (if skipped in read_it)
  • Should support standard R objects too.

Try to add {col_contains} column selector, which is based on content of the column

Here is the prototype

require(magrittr)
#> Loading required package: magrittr

select.df <- function(.x, ...) {
  pos <- tidyselect::eval_select(rlang::expr(c(...)), .x)
  rlang::set_names(.x[pos], names(pos))
}
rename.df <- function(.x, ...) {
  pos <- tidyselect::eval_rename(rlang::expr(c(...)), .x)
  names(.x)[pos] <- names(pos)
  .x
}


col_contains <- function(str, dat = tidyselect::peek_data(fn = "col_contains"), .ignore_case = T) {
  if(.ignore_case){
    str <- tolower(str)
    dat %>% 
      purrr::map_lgl(~.x %>% tolower() %>% stringr::str_detect(str) %>% any) %>% 
      colnames(dat)[.]
  }else{
    dat %>% 
      purrr::map_lgl(~stringr::str_detect(.x, str) %>% any) %>% 
      colnames(dat)[.]
  }
  
}


d <- iris
class(d)<- c( "df", class(d))


d %>% dplyr::rename(tst = col_contains("seto")) %>% head()
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width    tst
#> 1          5.1         3.5          1.4         0.2 setosa
#> 2          4.9         3.0          1.4         0.2 setosa
#> 3          4.7         3.2          1.3         0.2 setosa
#> 4          4.6         3.1          1.5         0.2 setosa
#> 5          5.0         3.6          1.4         0.2 setosa
#> 6          5.4         3.9          1.7         0.4 setosa
d %>% dplyr::select(col_contains("ginica")) %>% head()
#>   Species
#> 1  setosa
#> 2  setosa
#> 3  setosa
#> 4  setosa
#> 5  setosa
#> 6  setosa

Created on 2020-04-03 by the reprex package (v0.3.0)

Current State of Development and Way Forward

This is a trackable version of See DevNotes

  • Test it in r-hub
  • Test for optional shiny modules (series of visual_* functions)
  • Write more tests (increase coverage)
  • Write collate_columns function to deal with similar columns in composed data.frame
  • Making a pkgdown site
  • Releasing this package to CRAN
  • Make doc test skip on CRAN.
  • Make possibility for purrr like formula, e.g. ~ .x for tidycells::value_attribute_classify
  • A compatibility function for the "Heuristic Maturation" process (after CRAN)
  • Write blog + add it to R blogger and other sites
  • Send it to the r-packages mailing list
  • Explore options to add this in CRAN Task Views (not possible now)
  • make a cheatsheet
  • Explore SDMX Converter possibility
  • Explore other formats (containing unorganised tables) possibility. Check out unoconv.
  • Write more vignettes on other topics
  • Making cell analysis little faster

cell_df not retaining other columns

cell_df additional columns dropping in numeric_values_classifier
Similarly while coming from R-object to cell_df columns are getting dropped.
Need to fix this.

Add assistant

At least for Proof of Concept add a simple assistant

  • This should work automatically in Rstudio only.
  • It should work when the package is loaded.
  • Basically it is an overview in the viewer

Create a broader framework if found to be useful.

Logo Improvement

Minor changes should be done in Logo. Make sure to follow a standard structure.

  • Put the logo in man folder (check corrr). It should come in an interactive package help page help("tidycells").
  • Try to make is SVG (as the clarity is not great now) and test in various system.

Extend Support for other type of files

Once read_cells supports reading data as it is (see #7), extend it's the support for other types of files and objects.

  • If possible or required, depend on wand. For magic number based file type detection.
  • Support for all types mentioned in Data Import Cheat Sheet - by RStudio
  • xls : Already supported through readxl and xlsx
  • xlsx : Already supported through tidyxl
  • doc : Already supported through docxtractr but need a better alternative.
  • docx : Already supported through docxtractr
  • pdf : Already supported through tabulizer but need either better alternative or more clear guide to the user.
  • html, xml : Already supported through XML possibly need more clear guide and examples
  • All kind of delimited files : Few supported through read.csv and readr. Need to support other possiblities.
  • All haven types : Check all possible types under haven
    • SPSS
    • Stata
    • SAS

<information block> concept

The flow of the structure

  1. File Field (folder or zip files)
  2. Table Field Container (File, like excel with multiple sheets)
  3. Table Field (cell-df)
  4. Table

Now below a table

  1. information block (containing major attributes and data blocks)

Which contains

  1. data-blocks (or value blocks) as used in analyze_cells
  2. major attribute-blocks

So the difference between a table and an information block is that :

  • The table is a superset of an information block
  • The table is containing information block + minor attributes

So the minor attribute gets attached to each data-blocks in the information-block.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.