LoginSignup
2
1

More than 5 years have passed since last update.

R初心者がmapplyでハマった話

Last updated at Posted at 2018-07-29

この記事について

急遽手元にある~100万件程度の緯度経度データセットに対していわゆるリバースジオコーディングをやることになり、こちらの記事を読みながらやることにした。
リバースジオコーディング自体はうまくいったものの、普段Rを使っていないのでRの基本的なところでハマったので備忘録がてら。
結論、mapply() はlistを返すので、データフレームでそれを扱いたい場合、適切な後処理をしましょう以上のものではないですが、普段Rをほぼ書かないのでかなり頓珍漢なことをやっている可能性が高く、もっと良い方法をご存知の方がいましたらご教示いただけますと助かります。

ハマった時の状況

参考記事のリバースジオコーディング関数は、単一の緯度経度を受け付けて実行する形になっている。
ただし、手元にあるのはまとまった量のデータセットなので、for文とかでやるのは非効率。

適当にググったら、そういう時にはRでは apply() 関数ファミリーが便利だと知る。複数の引数を取る場合には mapply(func, arg1, arg2)書くと良いと知る

リバースジオコーディングの関数自体は(warningが出たものの)実行できた。
View()で結果を見てみると、いくつか欠損値はありつつも(これは想定通り)、いくつかデータをピックアップして結果を見比べてみても、正しくリバースジオコーディングができていそう。

しかし、結果をwrite_csv()で吐き出そうとしたところ、データフレームにlistはが含まれているため出力できない旨のエラーが出る。確かに、書き出したいデータフレームをhead()で見ると、mapply()関数の実行結果を格納した列の下(データ型?が書かれる部分)にlistと書いてある。

どういうことだってばよ???

解決策

結論、 mapply() で出力した結果は、データフレームの列に、単一のリストとして格納されてしまっていた。
(言い訳だけど、普段使っているpandasだとこういうことが起こらないので気づくまでにだいぶ時間がかかった。。)
なので、欠損値を補完してあげた上で unlist() でベクトル化?した結果を元の列に格納してあげることで解決した(ちなみに欠損値を補完せずにunlist()すると欠損値を含むrowが飛ばされてベクトル化しまい、元のデータフレームに結果を格納した際、欠損値が存在するrow以降のデータの順番が狂ってしまうのでダメ)。
コードは下記の通り。

# データ読み込み
df <- read_csv("my_geodata.csv")
# 都道府県レベルpolygon search(参考記事をベースに多少いじったもの)
df$pref <- mapply(find_city, df$lon, df$lat)
# データ整形(欠損値の補完とdfの型変換)
prefs <- lapply(df$pref, function(x) if (length(x) == 0) 0 else x)
df$pref <- unlist(prefs)
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1