Rで空行・空列を除去する方法

概要
R言語を用いて、表型のデータに含まれる空行・空列を取り除く方法について紹介する。

余計な空行・空列を含むデータ

表計算ソフト上での見た目を良くするためだろうか、表型のデータに余計な空行・空列が含まれていることは少なくない。例えば、以下の表を見てもらいたい。これは、架空の会社について各地の支店の社員数を示したものだ。

表計算ソフト上での見た目は良いかもしれないが、空行・空列を含むため、データ分析がしにくくなってしまっている。
表計算ソフト上での見た目は良いかもしれないが、空行・空列を含むため、データ分析がしにくくなってしまっている。

この表には、余計な空行がある。

2行目・4行目・8行目・11行目が何もデータを持たない空行となっている。
2行目・4行目・8行目・11行目が何もデータを持たない空行となっている。

さらに、余計な空列もある。

2列目が何もデータを持たない空列となっている。このような空行・空列はデータ分析の際には邪魔になる。
2列目が何もデータを持たない空列となっている。このような空行・空列はデータ分析の際には邪魔になる。

こうした空行・空列が存在しているままだと、データ分析がしにくくなる。以下では、R言語においてこうした空行空列除去する方法を紹介したい。

準備

空欄判定用の函数

まず、今後の処理のために、空欄かどうかを判定する函数 is_blank() を定義しておこう。これは、引数が NA か空の文字列("")ならば、TRUE を返すものである [1]

#  is_blank の定義
is_blank <- function(x) {is.na(x) | x == ""}

データの読み込み

次に、データをRに読みこもう。冒頭で示した表のデータが、r-blank-example1.csv というCSVファイルの中に入っているものとする。

# データの読み込み
df <- read.csv("r-blank-example1.csv", fileEncoding = "UTF-8")

この時点での df の中身は以下のようになっている。

支店名 X 社員数
1
2 札幌支店 43
3
4 青森支店 21
5 盛岡支店 18
6 仙台支店 33
7
8 宇都宮支店 19
9 千葉支店 32
10
11 広島支店 41
12 岡山支店 31
13 倉敷支店 15

空行・空列の除去

空行というのは、要するにその行の要素のすべてが空欄となっている行のことである。だから、空行を探すために、apply() 函数を使って、1行ごとにその行の要素がすべて (all()) 空欄かどうか (is_blank()) を判定していく。

# すべてが空欄である行を探す
unnecessary_row <- apply(df, 1,
                         function(x){
                           all(is_blank(x))
                        })

# 「すべてが空欄である行」以外を残す(=空行の除去)
df <- df[!unnecessary_row,]

空列を探すときも同様で、apply() 函数を使って、1列ごとにその列の要素がすべて空欄かどうかを判定していく。

# すべてが空欄である列を探す
unnecessary_col <- apply(df, 2,
                         function(x){
                           all(is_blank(x))
                         })
# 「すべてが空欄である列」以外を残す(=空列の除去)
df <- df[, !unnecessary_col]

このようにすれば、空行・空列が除去される。最終的に、df の中身は次のようになる。

支店名 社員数
1 札幌支店 43
2 青森支店 21
3 盛岡支店 18
4 仙台支店 33
5 宇都宮支店 19
6 千葉支店 32
7 広島支店 41
8 岡山支店 31
9 倉敷支店 15

別解

参考のために、空行・空列を除去する別の方法も挙げておこう。

この方法では、空行を除去するために、行ごとに空欄の数が合わせていくつになるかを求め、それが列の数(=1行に含まれるすべての要素の数)と等しくないものを残すようにしている。1行に含まれる空欄の数が、その行に含まれるすべての要素の数と等しければ、それは空行ということになる。等しくないものを残せば、空行が除去されるというわけである。

library("tidyverse")

#  is_blank の定義
is_blank <- function(x) {is.na(x) | x == ""}

# データの読み込み
df <- read_csv("r-blank-example1.csv")

# 整形
df <- df %>%
  # 空行の除去
  filter(
    rowSums(is_blank(.)) != ncol(.)
  ) %>%
  # 空列の除去
  select_if(
    colSums(is_blank(.)) != nrow(.)
  )

ちなみに、select_if() を使う部分は、以下のように書き換えても同じことができる。

select_if(
  function(x){
    sum(is.blank(x)) != NROW(x)
  })
脚注
  1. 表計算ソフト上で空欄に見えるところは、Rで読みこむと基本的に NA か空の文字列("")になる。 []