データフレーム(data.frame)を一行ずつ処理したい

ナウく書きたい。

rmap でもいいけど、以下のように purrr::pmap() が良さげ。

> head(iris, 3) %>%
+   purrr::pmap_dfr(function(...) {
+     df_row <- tibble(...)
+     print(df_row)
+     df_row
+   })
# A tibble: 1 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
         <dbl>       <dbl>        <dbl>       <dbl> <fct>  
1          5.1         3.5          1.4         0.2 setosa 
# A tibble: 1 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
         <dbl>       <dbl>        <dbl>       <dbl> <fct>  
1          4.9           3          1.4         0.2 setosa 
# A tibble: 1 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
         <dbl>       <dbl>        <dbl>       <dbl> <fct>  
1          4.7         3.2          1.3         0.2 setosa 
# A tibble: 3 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
         <dbl>       <dbl>        <dbl>       <dbl> <fct>  
1          5.1         3.5          1.4         0.2 setosa 
2          4.9         3            1.4         0.2 setosa 
3          4.7         3.2          1.3         0.2 setosa 

参考

ggplot2の軸とかに数式を使いたい

expression 使えばよろし。

library("mmetrics")
df <- gsummarise(iris, Species, metrics = define(y=sum(Petal.Width)))

ggplot(df, aes(x = Species, y = y)) +
  geom_bar(position = "dodge", color="black", stat="identity") + 
  labs(x = expression(alpha["100"]), y=expression(paste(rho["1"], ", ", rho["2"]))) 

f:id:teramonagi:20190831120015p:plain

特異値分解の検算

すぐ忘れる。 svd関数の戻り値をxとして x$u %*% diag(x$d) %*% t(x$v) で元通り。

> b <- array(rnorm(10), dim=c(5,2))
> b
           [,1]         [,2]
[1,] -0.5036082 -1.218417405
[2,] -0.7905285  1.331412278
[3,]  0.8311744 -0.147847237
[4,] -0.8628976  0.681707538
[5,] -1.1254487 -0.007460698
> b_svd <- svd(b)
> u <- b_svd$u
> v <- b_svd$v
> sigma <- diag(b_svd$d)
> u %*% sigma %*% t(v)
           [,1]         [,2]
[1,] -0.5036082 -1.218417405
[2,] -0.7905285  1.331412278
[3,]  0.8311744 -0.147847237
[4,] -0.8628976  0.681707538
[5,] -1.1254487 -0.007460698
> b
           [,1]         [,2]
[1,] -0.5036082 -1.218417405
[2,] -0.7905285  1.331412278
[3,]  0.8311744 -0.147847237
[4,] -0.8628976  0.681707538
[5,] -1.1254487 -0.007460698

ある関数のデフォルト引数がある引数のみを、そのデフォルト引数とともに抜く

例えばここにこんな関数があったとする。

f <- function(x, y = 100, args = list()){
  y
}

そしてこの関数のデフォルト引数がある引数のみを、そのデフォルト引数とともに抜きたいと思うことがある、俺にはある。 こういう処理をしてくれる関数 get_default_args が欲しいということだ

> get_default_args(f)
$y
[1] 100

$args
list()

このような関数は以下のように実装することができる。 詳細はCodeコメントを読んで欲しい。

get_default_args <- function(func){
  # formalsで引数とデフォルト引数をまとめてとれる。ただしpairlist型なので無理やりlistにする
  x <- as.list(formals(func))
  # デフォルト引数のない引数(上のk名数fでいうx)はnameオブジェクトと判定されるので、それ以外(デフォルト引数ある引数)をもってくる
  has_default_value <- purrr::map_lgl(x, ~ !is.name(.x))
  purrr::keep(x, has_default_value)
}

各大グループにおいて、各小グループの値がどの程度の割合を占めているのかを出す

昔、 r-wakalangで教えてもらったがメモってなかった話なのでメモっておく。 こういうデータ df があった時に

> df <- data.frame(
+   big_group=rep(letters[1:2], 30),
+   small_group=rep(1:3, 10),
+   value=runif(30)
+ )
> head(df, 10)
   big_group small_group      value
1          a           1 0.44153360
2          b           2 0.85443783
3          a           3 0.70604936
4          b           1 0.76551800
5          a           2 0.42258650
6          b           3 0.07403564
7          a           1 0.41088446
8          b           2 0.61669153
9          a           3 0.57614474
10         b           1 0.57685482

このデータの「各大グループにおいて、各小グループの値がどの程度の割合を占めているのか」を出す場合には以下のようにかく。 一回 summarizeかますとグルーピングが1個外れるってのがみそ(最終的には大グループでのみグルーピングされたデータになっている)。

> library(dplyr, warn.conflicts = FALSE)
> df %>%
+   dplyr::group_by(big_group, small_group) %>%
+   dplyr::summarise(sum_value = sum(value)) %>%
+   dplyr::mutate(ratio_value = sum_value / sum(sum_value))
# A tibble: 6 x 4
# Groups:   big_group [2]
  big_group small_group sum_value ratio_value
  <fct>           <int>     <dbl>       <dbl>
1 a                   1      3.93       0.307
2 a                   2      4.82       0.376
3 a                   3      4.06       0.317
4 b                   1      5.91       0.385
5 b                   2      6.37       0.416
6 b                   3      3.05       0.199