列のフォーマット

library(tibble)

概要

この vignette は、カスタムフォーマットのために列を装飾する方法を示します。 フォーマット可能なパッケージには、数字にカスタムフォーマットを適用するための便利なベクトルクラスがすでに含まれているので、デモンストレーションに使用します。

library(formattable)

tbl <- tibble(x = digits(9:11, 3))
tbl
#> # A tibble: 3 x 1
#>   x         
#>   <formttbl>
#> 1 9.000     
#> 2 10.000    
#> 3 11.000

上の tibble のx列は、フォーマット方法のある正規の数値です。 常に小数点以下3桁の数字で表示されます。 これは x から派生した列にも適用されます。

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
tbl2 <- 
  tbl %>%
  mutate(
    y = x + 1, 
    z = x * x, 
    v = y + z,
    lag = lag(x, default = x[[1]]),
    sin = sin(x),
    mean = mean(v),
    var = var(x)
  )

tbl2
#> # A tibble: 3 x 8
#>           x         y         z         v       lag       sin      mean   var
#>   <dbl:fmt> <dbl:fmt> <dbl:fmt> <dbl:fmt> <dbl:fmt> <dbl:fmt> <dbl:fmt> <dbl>
#> 1     9.000    10.000    81.000    91.000     9.000     0.412   111.667     1
#> 2    10.000    11.000   100.000   111.000     9.000    -0.544   111.667     1
#> 3    11.000    12.000   121.000   133.000    10.000    -1.000   111.667     1

また、サマリーはフォーマットを維持しています。

tbl2 %>% 
  group_by(lag) %>% 
  summarize(z = mean(z)) %>% 
  ungroup()
#> # A tibble: 2 x 2
#>         lag         z
#>   <dbl:fmt> <dbl:fmt>
#> 1     9.000    90.500
#> 2    10.000   121.000

ピボット操作も同様です。

library(tidyr)

stocks <- 
  expand_grid(id = factor(1:4), year = 2018:2022) %>% 
  mutate(stock = currency(runif(20) * 10000))

stocks %>% 
  pivot_wider(id, names_from = year, values_from = stock)
#> # A tibble: 4 x 6
#>   id       `2018`    `2019`    `2020`    `2021`    `2022`
#>   <fct> <dbl:fmt> <dbl:fmt> <dbl:fmt> <dbl:fmt> <dbl:fmt>
#> 1 1     $7,316.37   $419.38 $3,568.69 $2,456.73 $9,555.52
#> 2 2     $7,906.53 $9,203.96 $7,247.49 $2,121.73 $8,343.59
#> 3 3     $4,504.02 $2,576.06 $3,219.48 $5,140.65 $6,213.98
#> 4 4     $5,894.35 $5,483.22 $8,945.23 $5,162.64 $2,282.67

ggplot2 では、スケールにフォーマットを適用することを示すために、いくつかの作業を行う必要があります。

library(ggplot2)
#> Error: package or namespace load failed for 'ggplot2' in loadNamespace(i, c(lib.loc, .libPaths()), versionCheck = vI[[i]]):
#>  there is no package called 'colorspace'

# Needs https://github.com/tidyverse/ggplot2/pull/4065 or similar
stocks %>% 
  ggplot(aes(x = year, y = stock, color = id)) +
  geom_line()
#> Error in ggplot(., aes(x = year, y = stock, color = id)):  関数 "ggplot" を見つけることができませんでした

プロセスの非常に早い段階でフォーマットを指定することは有益です。 下の図は、「R for data science」に掲載されているデータ分析・探索の主な段階を示したものです。

後続の図では、データフォーマット、通信オプション、明示的なデータフォーマットが追加されています。 オリジナルのR4Dトランジションは太字で表示されています。 結果のフォーマットを適用する場所は、通信する直前と、インポートした直後の2つの主要なオプションがあります。

Ensuring stickiness is difficult, and is insufficient for a dbplyr workflow where parts of the “Tidy”, “Transform” or even “Visualize” stages are run on the database. Often it’s possible to derive a rule-based approach for formatting.

プロセスの早い段階でフォーマットを適用すると、「Tidy」、「Transform」、「Visualize」の各段階で、データを有用なフォーマットで表示できるという利点があります。 そのためには、早い段階でフォーマットオプションを適用しておく必要があります。

「Tidy」、「Transform」、「Visualize」ステージの一部がデータベース上で実行されるような dbplyr のワークフローでは、粘着性を確保することは困難であり、不十分です。 多くの場合、フォーマットのためのルールベースのアプローチを導き出すことができます。

tbl3 <- 
  tibble(id = letters[1:3], x = 9:11) %>% 
  mutate(
    y = x + 1, 
    z = x * x, 
    v = y + z,
    lag = lag(x, default = x[[1]]),
    sin = sin(x),
    mean = mean(v),
    var = var(x)
  )

tbl3
#> # A tibble: 3 x 9
#>   id        x     y     z     v   lag    sin  mean   var
#>   <chr> <int> <dbl> <int> <dbl> <int>  <dbl> <dbl> <dbl>
#> 1 a         9    10    81    91     9  0.412  112.     1
#> 2 b        10    11   100   111     9 -0.544  112.     1
#> 3 c        11    12   121   133    10 -1.00   112.     1

tbl3 %>% 
  mutate(
    across(where(is.numeric), digits, 3),
    across(where(~ is.numeric(.x) && mean(.x) > 50), digits, 1)
  )
#> # A tibble: 3 x 9
#>   id            x        y        z        v      lag      sin     mean      var
#>   <chr> <dbl:fmt> <dbl:fm> <dbl:fm> <dbl:fm> <dbl:fm> <dbl:fm> <dbl:fm> <dbl:fm>
#> 1 a         9.000   10.000     81.0     91.0    9.000    0.412    111.7    1.000
#> 2 b        10.000   11.000    100.0    111.0    9.000   -0.544    111.7    1.000
#> 3 c        11.000   12.000    121.0    133.0   10.000   -1.000    111.7    1.000

これらのルールは、quos()に格納することができます。:

rules <- quos(
  across(where(is.numeric), digits, 3),
  across(where(~ is.numeric(.x) && mean(.x) > 50), digits, 1)
)

tbl3 %>% 
  mutate(!!!rules)
#> # A tibble: 3 x 9
#>   id            x        y        z        v      lag      sin     mean      var
#>   <chr> <dbl:fmt> <dbl:fm> <dbl:fm> <dbl:fm> <dbl:fm> <dbl:fm> <dbl:fm> <dbl:fm>
#> 1 a         9.000   10.000     81.0     91.0    9.000    0.412    111.7    1.000
#> 2 b        10.000   11.000    100.0    111.0    9.000   -0.544    111.7    1.000
#> 3 c        11.000   12.000    121.0    133.0   10.000   -1.000    111.7    1.000

これにはいくつかの欠点があります。

ルールベースのフォーマットのための優れたAPIとはどのようなものでしょうか?