R(tidyverse)

2025年1月29日 (水)

[R]Apacheのログファイルの日付列から日付時刻型ベクトルを作成する

tidyverseパッケージを読み込むと読み込まれるlubridateパッケージのparse_date_time関数を使う。以下は15行からなるサンプルのApacheのログファイルを読み込み、日付列(4列目)を日付時刻型ベクトルに変換した例。

> library(tidyverse)
> options(readr.show_progress = FALSE, readr.show_col_types = FALSE)
> tib <- read_log("access.log")
> dim(tib)
[1] 15 9
> tib[, 1:6] |> as.data.frame()
X1 X2 X3 X4 X5 X6
1 192.168.12.2 NA NA 06/Dec/2024:23:51:07 +0900 GET / HTTP/1.1 200
2 192.168.12.2 NA NA 06/Dec/2024:23:51:07 +0900 GET /icons/ubuntu-logo.png HTTP/1.1 200
3 192.168.12.2 NA NA 06/Dec/2024:23:51:07 +0900 GET /favicon.ico HTTP/1.1 404
4 192.168.12.4 NA NA 06/Dec/2024:23:53:49 +0900 GET / HTTP/1.1 200
5 192.168.12.4 NA NA 06/Dec/2024:23:53:49 +0900 GET /icons/ubuntu-logo.png HTTP/1.1 200
6 192.168.12.4 NA NA 06/Dec/2024:23:53:49 +0900 GET /favicon.ico HTTP/1.1 404
7 192.168.12.4 NA NA 06/Dec/2024:23:54:23 +0900 GET / HTTP/1.1 200
8 192.168.12.4 NA NA 06/Dec/2024:23:54:23 +0900 GET /icons/ubuntu-logo.png HTTP/1.1 200
9 192.168.12.4 NA NA 06/Dec/2024:23:54:23 +0900 GET /favicon.ico HTTP/1.1 404
10 192.168.12.4 NA NA 06/Dec/2024:23:55:14 +0900 408
11 192.168.12.4 NA NA 06/Dec/2024:23:56:56 +0900 GET / HTTP/1.1 200
12 192.168.12.4 NA NA 06/Dec/2024:23:56:56 +0900 GET /icons/ubuntu-logo.png HTTP/1.1 200
13 192.168.12.4 NA NA 06/Dec/2024:23:56:56 +0900 GET /favicon.ico HTTP/1.1 404
14 192.168.12.4 NA NA 06/Dec/2024:23:57:04 +0900 GET / HTTP/1.1 200
15 192.168.12.4 NA NA 06/Dec/2024:23:57:55 +0900 408
> Sys.timezone()
[1] "Asia/Tokyo"
> parse_date_time(tib$X4, "%d/%m/%Y:%H:%M:%S %z")
[1] "2024-12-06 14:51:07 UTC" "2024-12-06 14:51:07 UTC" "2024-12-06 14:51:07 UTC"
[4] "2024-12-06 14:53:49 UTC" "2024-12-06 14:53:49 UTC" "2024-12-06 14:53:49 UTC"
[7] "2024-12-06 14:54:23 UTC" "2024-12-06 14:54:23 UTC" "2024-12-06 14:54:23 UTC"
[10] "2024-12-06 14:55:14 UTC" "2024-12-06 14:56:56 UTC" "2024-12-06 14:56:56 UTC"
[13] "2024-12-06 14:56:56 UTC" "2024-12-06 14:57:04 UTC" "2024-12-06 14:57:55 UTC"
> parse_date_time(tib$X4, "%d/%m/%Y:%H:%M:%S %z", tz = "Asia/Tokyo")
Date in ISO8601 format; converting timezone from UTC to "Asia/Tokyo".
[1] "2024-12-06 23:51:07 JST" "2024-12-06 23:51:07 JST" "2024-12-06 23:51:07 JST"
[4] "2024-12-06 23:53:49 JST" "2024-12-06 23:53:49 JST" "2024-12-06 23:53:49 JST"
[7] "2024-12-06 23:54:23 JST" "2024-12-06 23:54:23 JST" "2024-12-06 23:54:23 JST"
[10] "2024-12-06 23:55:14 JST" "2024-12-06 23:56:56 JST" "2024-12-06 23:56:56 JST"
[13] "2024-12-06 23:56:56 JST" "2024-12-06 23:57:04 JST" "2024-12-06 23:57:55 JST"
> dttm <- parse_date_time(tib$X4, "%d/%m/%Y:%H:%M:%S %z", tz = "Asia/Tokyo")
Date in ISO8601 format; converting timezone from UTC to "Asia/Tokyo".
> class(dttm)
[1] "POSIXct" "POSIXt"

上記のとおりparse_date_time関数は読み込んだ日付時刻を強制的にUTCと判断して変換する。そのため、読み込む際には明示的にタイムゾーンを指定する必要がある。変換された日付時刻型ベクトルのクラスはPOSIXctである。

2024年12月20日 (金)

[R]read_csv関数で読み込まれる日付時刻型ベクトルについて

CSVファイルにタイムゾーンも明記されている場合は、そのタイムゾーンの日付時刻として読み取るが、ベクトルにはUTCに変換して保存される。

タイムゾーンが明記されていない日付時刻は強制的にUTCであるとして読み込み、保存されてしまう。読み込み後にJSTにする場合は、force_tz関数でタイムゾーンだけをJSTに変える必要がある。

> library(tidyverse)
> options(readr.show_progress = FALSE, readr.show_col_types = FALSE)
> Sys.timezone()
[1] "Asia/Tokyo"
> s <- "2001-02-03T04:05:06+09:00"
> dtf <- data.frame(dttm = s)
> write_csv(dtf, file = "temp.csv")
> cat(read_file("temp.csv"))
dttm
2001-02-03T04:05:06+09:00
> tib <- read_csv("temp.csv")
> print(tib$dttm)
[1] "2001-02-02 19:05:06 UTC"
> s <- "2001-02-03T04:05:06"
> dtf <- data.frame(dttm = s)
> write_csv(dtf, file = "temp.csv")
> cat(read_file("temp.csv"))
dttm
2001-02-03T04:05:06
> tib <- read_csv("temp.csv")
> print(tib$dttm)
[1] "2001-02-03 04:05:06 UTC"
> tib <- tib |> mutate(dttm = force_tz(dttm, tzone = Sys.timezone()))
> print(tib$dttm)
[1] "2001-02-03 04:05:06 JST"

2024年12月19日 (木)

[R]write_csv関数で出力される日付時刻型ベクトルについて

日付時刻型ベクトルを出力すると、UTCに変換されて出力されることに注意。なお、日付型ベクトルは当然この影響を受けない。

現在の環境の日時を表す文字列で出力したければ、文字列に変換する必要がある。

> library(tidyverse)
> options(readr.show_progress = FALSE, readr.show_col_types = FALSE)
> print(Sys.timezone())
[1] "Asia/Tokyo"
> dttm <- ymd_hms("2001-02-03 04:05:06")
> dat <- ymd("2010-11-12")
> print(dttm)
[1] "2001-02-03 04:05:06 UTC"
> print(dat)
[1] "2010-11-12"
> dtf <- data.frame(dttm, dat)
> write_csv(dtf, file = "temp.csv")
> cat(read_file("temp.csv"))
dttm,dat
2001-02-03T04:05:06Z,2010-11-12
> dttm <- ymd_hms("2001-02-03 04:05:06", tz = Sys.timezone())
> print(dttm)
[1] "2001-02-03 04:05:06 JST"
> dtf <- data.frame(dttm)
> write_csv(dtf, file = "temp.csv")
> cat(read_file("temp.csv"))
dttm
2001-02-02T19:05:06Z
> s <- format(dttm, "%Y-%m-%dT%H:%M:%S")
> print(s)
[1] "2001-02-03T04:05:06"
> dtf <- data.frame(dttm = s)
> write_csv(dtf, file = "temp.csv")
> cat(read_file("temp.csv"))
dttm
2001-02-03T04:05:06
> s = format(dttm, "%Y-%m-%dT%H:%M:%S%z")
> print(s)
[1] "2001-02-03T04:05:06+0900"
> dtf <- data.frame(dttm = s)
> write_csv(dtf, file = "temp.csv")
> cat(read_file("temp.csv"))
dttm
2001-02-03T04:05:06+0900

2024年12月13日 (金)

[R]tibbleに新しい列を追加する

add_column関数を使う。.afterオプション(.beforeオプションもある)を使うと任意の位置に追加することができる。

> library(tibble)
> no <- 1:2
> name <- c("セナディア", "イレイナ")
> tib <- tibble(no, name)
> tib |> as.data.frame()
no name
1 1 セナディア
2 2 イレイナ
> seiyu <- c("鈴木みのり", "本渡楓")
> tib <- tib |> add_column(seiyu = seiyu)
> tib |> as.data.frame()
no name seiyu
1 1 セナディア 鈴木みのり
2 2 イレイナ 本渡楓
> tib <- tib |> add_column(seiyu2 = seiyu, .after = no)
> tib |> as.data.frame()
no seiyu2 name seiyu
1 1 鈴木みのり セナディア 鈴木みのり
2 2 本渡楓 イレイナ 本渡楓

2024年11月26日 (火)

[R]tibbleで特定の列の値を基準にして集計を行う

例えば家計簿のように、日にちと金額が一対一で対応しているデータについて、毎日の入出金の流れを見たい場合など。

各情報の基準は日にちであり、同じ日にいくつも入金や出金が発生する日があり、この基準となる日付には重複がある。このようなデータを一覧で見るぶんにはよいが、毎日の入出金の流れはこれでは見ることはできない。この例では、日ごとに金額の集計を行いたい。この場合は、日にちごとの金額の和を計算してまとめたい。

このような場合は、group_by関数でtibble内部でグループ化を行い、それをsummarize関数で処理することで、集計後のtibbleに変換することができる。以下、実行例。表示を簡潔にするため、データフレームに変換して表示している。

> tib %>% as.data.frame()
date type value
1 2023-10-03 入金 200
2 2023-10-04 電気 4
3 2023-10-07 ガス 5
4 2023-10-07 電話 7
5 2023-10-09 水道 6
> tib %>% group_by(date) %>% as.data.frame()
date type value
1 2023-10-03 入金 200
2 2023-10-04 電気 4
3 2023-10-07 ガス 5
4 2023-10-07 電話 7
5 2023-10-09 水道 6
> tib %>% group_by(date) %>% summarize(value = sum(value)) %>% as.data.frame()
date value
1 2023-10-03 200
2 2023-10-04 4
3 2023-10-07 12
4 2023-10-09 6

group_by関数は内部でグループ化を行っているだけであり、2番目の実行例のとおりgroup_by関数だけでは集計が行われない(表示されない)ことに注意。

2024年11月25日 (月)

[R]read_xlsx関数を使うと画面表示が乱れる(カーソルが飛ぶ)

readxlパッケージのread_xlsx関数は、デフォルトでは、読み込み時に実際は表示されないものの経過を画面表示しようとするため、その影響で、使用後は画面表示が乱れ、カーソルがおかしなところに飛んでしまう。この画面表示の乱れが起きないようにするには、progressオプションにFALSEを指定する。

> library(readxl)
> tib <- read_xlsx("sample.xlsx")

←カーソルがコマンドラインのプロンプトから離れた箇所に表示され、表示が乱れる。

一度Rを終了し、再起動して次のコマンドを実行する。

> library(readxl)
> tib <- read_xlsx("sample.xlsx", progress = FALSE)

←カーソルがコマンドラインのプロンプトのすぐ右側に表示され、表示が乱れない。

以下を.RProfileに記述しておけば、R起動時に自動的に読み込み、デフォルトでそのような設定になる。

options(
readxl.show_progress = FALSE
)

R起動後でも、以下のコマンドを実行すれば同じようにデフォルトでそのような設定になる。

options(readxl.show_progress = FALSE)

2024年10月15日 (火)

[R]画面表示でtibbleの中身を任意の行数出力する

tibbleは画面表示を任意の行数にするにはprint関数を使用してnオプションに必要な行数を指定すればよい。

> library(tidyverse)
> nn <- 20
> n <- 1:nn
> s0 <- c("鈴木みのり", "近藤唯", "会沢紗弥")
> s <- sample(s0, nn, replace = TRUE)
> tib <- tibble(n, s)
> tib
# A tibble: 20 × 2
n s
<int> <chr>
1 1 鈴木みのり
2 2 近藤唯
3 3 近藤唯
4 4 会沢紗弥
5 5 会沢紗弥
6 6 近藤唯
7 7 近藤唯
8 8 会沢紗弥
9 9 鈴木みのり
10 10 会沢紗弥
11 11 会沢紗弥
12 12 会沢紗弥
13 13 会沢紗弥
14 14 近藤唯
15 15 近藤唯
16 16 近藤唯
17 17 鈴木みのり
18 18 会沢紗弥
19 19 会沢紗弥
20 20 鈴木みのり
> print(tib, n = 4)
# A tibble: 20 × 2
n s
<int> <chr>
1 1 鈴木みのり
2 2 近藤唯
3 3 近藤唯
4 4 会沢紗弥
# ℹ 16 more rows
# ℹ Use `print(n = ...)` to see more rows
> tib %>% print(n = 4)
# A tibble: 20 × 2
n s
<int> <chr>
1 1 鈴木みのり
2 2 近藤唯
3 3 近藤唯
4 4 会沢紗弥
# ℹ 16 more rows
# ℹ Use `print(n = ...)` to see more rows

2024年4月29日 (月)

[R]read_lines関数で様々な文字コードのテキストファイルを読み込む

localeオプションを使用する。はじめに、この動作確認のためのテキストファイルをPowerShellで作成する。それぞれ文字コードがシフトJISとUTF-8(BOM無し)のCSVファイルを作成している。

PS > $lines = "1,セナディア,鈴木みのり", "2,イレイナ,本渡楓"
PS > $odir = (gl).Path
PS > $lines | Out-File -Encoding default ($odir + "\sjis.csv")
PS > [IO.File]::WriteAllLines(($odir + "\utf8nb.csv"), $lines)
PS > Get-Content sjis.csv
1,セナディア,鈴木みのり
2,イレイナ,本渡楓
PS > Get-Content utf8nb.csv -Encoding utf8
1,セナディア,鈴木みのり
2,イレイナ,本渡楓

read_lines関数を使用する際に、localeオプションに文字コードを指定すればよい。以下の例のとおり、デフォルトではUTF-8で読み込もうとするため、UTF-8であれば明示的に指定しなくてもかまわない。

> library(tidyverse)
> read_lines("sjis.csv", progress = FALSE)
[1] "1,<83>Z<83>i<83>f<83>B<83>A,<97><96><U+0602><U+0742><U+0302>" "2,<83>C<83><8c><83>C<83>i,<96>{<93>n<95><96>"
> read_lines("sjis.csv", progress = FALSE, locale = locale(encoding = "SJIS"))
[1] "1,セナディア,鈴木みのり" "2,イレイナ,本渡楓"
> read_lines("utf8nb.csv", progress = FALSE)
[1] "1,セナディア,鈴木みのり" "2,イレイナ,本渡楓"
> read_lines("utf8nb.csv", progress = FALSE, locale = locale(encoding = "UTF-8"))
[1] "1,セナディア,鈴木みのり" "2,イレイナ,本渡楓"

2024年4月 9日 (火)

[R]ある列の重複を除いた個数を調べる

group_by関数で列を指定してグループ化し、summarize関数で集計する。集計時にn関数を指定すると、その個数を返す。以下はあらかじめ用意したtibbleで実行した例。

> library(tidyverse)
> tib %>% as.data.frame()
nama title seiyu
1 ライスシャワー ウマ娘 石見舞菜香
2 スーパークリーク ウマ娘 優木かな
3 メイショウドトウ ウマ娘 和多田美咲
4 フィー ライザのアトリエ2 和多田美咲
5 黒川あかね 推しの子 石見舞菜香
> tib %>% group_by(title) %>% summarize(nn = n()) %>% as.data.frame()
title nn
1 ウマ娘 3
2 ライザのアトリエ2 1
3 推しの子 1
> tib %>% group_by(seiyu) %>% summarize(nn = n()) %>% as.data.frame()
seiyu nn
1 優木かな 1
2 和多田美咲 2
3 石見舞菜香 2
グループ化には2つ以上の列を同時に指定することもできる。
> tib2 <- bind_rows(tib, slice(tib, c(1, 1, 3)))
> tib2 %>% as.data.frame()
nama title seiyu
1 ライスシャワー ウマ娘 石見舞菜香
2 スーパークリーク ウマ娘 優木かな
3 メイショウドトウ ウマ娘 和多田美咲
4 フィー ライザのアトリエ2 和多田美咲
5 黒川あかね 推しの子 石見舞菜香
6 ライスシャワー ウマ娘 石見舞菜香
7 ライスシャワー ウマ娘 石見舞菜香
8 メイショウドトウ ウマ娘 和多田美咲
> tib2 %>% group_by(title, seiyu) %>% summarize(nn = n()) %>% as.data.frame()
`summarise()` has grouped output by 'title'. You can override using the `.groups` argument.
title seiyu nn
1 ウマ娘 優木かな 1
2 ウマ娘 和多田美咲 2
3 ウマ娘 石見舞菜香 3
4 ライザのアトリエ2 和多田美咲 1
5 推しの子 石見舞菜香 1

2024年4月 7日 (日)

[R]tibbleで特殊な列名を使用して操作する

例えばASCIIの0~9で始まる名前は通常は列名に使用できないが、バックティック(`)で挟むと使用することができるようになる。

> library(tidyverse)
> tib <- tibble(21世紀 = 1:4)
エラー: 想定外のシンボルです ( "tib <- tibble(21世紀" の)
> tib <- tibble(`21世紀` = 1:4)
> tib %>% as.data.frame()
21世紀
1 1
2 2
3 3
4 4
> tib %>% filter(`21世紀` >= 3) %>% as.data.frame()
21世紀
1 3
2 4

より以前の記事一覧

無料ブログはココログ

■■

■■■