言ってやるが、私は以下のようなデータフレームがあります。R:高速クエリ/マッチデータフレーム
library(dplyr)
library(microbenchmark)
library(ggplot2)
dfr <- data.frame(name=c("bill","john","alice","sara"),
job=c("accounting","business","finance","business"),
stringsAsFactors=F)
name job
1 bill accounting
2 john business
3 alice finance
4 sara business
をそして私は名前のクエリ(文字ベクトル)を持っています。私は、データフレームの位置「名前」に、クエリの各要素を検索し、いくつかの条件を指定した行全体を取得したいと思います
qe <- c("john","bill","mark","bill")
:クエリで
- 重複はの
- 注文を保存しなければなりませんクエリは
(NAの追加で)
loopy <- function(qe=NULL,dfr=NULL)
{
elist <- vector("list",length=length(qe))
for(i in 1:length(qe))
{
g <- grep(qe[i],dfr$name)
if(length(g)==0) {
elist[[i]] <- data.frame(name=qe[i],job=NA,stringsAsFactors=F)
}else{
elist[[i]] <- dfr[g,]
}
}
return(bind_rows(elist))
}
loopy(qe,dfr)
name job
1 john business
2 bill accounting
3 mark <NA>
4 bill accounting
私の実際のデータは数千の行で遅すぎます。私はdplyrのアプローチを試みると思った。
dp_lj <- function(qe=NULL,dfr=NULL)
{
edf <- data.frame(name=qe,stringsAsFactors=F)
edf <- left_join(edf,dfr,by="name")
return(edf)
}
dp_lj(qe,dfr)
name job
1 john business
2 bill accounting
3 mark <NA>
4 bill accounting
left_join
私が望む結果を与えるように思われます。しかし、驚くべきことに、これは私の虚偽の機能よりも遅かった。しばらく回って、私はマッチアプローチを思いついた。
matchy <- function(qe=NULL,dfr=NULL)
{
edf <- dfr[match(qe,dfr$name),]
pos <- match(NA,edf$name)
if(!is.na(pos)) edf[pos,]$name <- qe[pos]
rownames(edf) <- 1:nrow(edf)
return(edf)
}
matchy(qe,dfr)
name job
1 john business
2 bill accounting
3 mark <NA>
4 bill accounting
これはこれまでのところ最も速いです。 %in%
を使った試みは実際には機能しませんでした 3210
autoplot(microbenchmark(loopy(qe,dfr),dp_lj(qe,dfr),matchy(qe,dfr),times=500))
Unit: microseconds
expr min lq mean median uq max neval cld
loopy(qe, dfr) 426.274 461.0390 528.1194 481.7795 518.915 2659.955 500 b
dp_lj(qe, dfr) 919.311 982.9155 1146.0196 1030.1260 1129.088 4589.438 500 c
matchy(qe, dfr) 128.396 154.4710 185.1209 169.0875 186.471 736.397 500 a
あまりにも多くの努力を取らないより速く解決策がある場合、私は好奇心旺盛です。また、実際の大規模なデータセットで実行すると、ここで見られるパフォーマンスが同等かどうかはテストしていません。
EDIT --------------------------------------------- ----------------------------
提案されているようにdata.tableアプローチを追加しました。
dt <- function(qe=NULL,dfr=NULL)
{
setDT(dfr)
qe <- data.table(name=qe)
merge(qe, dfr, "name", all.x = TRUE, sort = FALSE)
}
は、長さ18と100,000行のデータフレームのクエリを使用して試験しました。現実のパフォーマンスをよりよく比較することができます。
mb <- microbenchmark(loopy(qe,dfr),dp_lj(qe,dfr),matchy(qe,dfr),dt(qe,dfr),times=200)
autoplot(mb)
あなたは 'fastmatch'パッケージをチェックアウトするかもしれません。これは複数の検索で 'match 'を破棄する' match'のためのドロップイン関数を持っています。 – lmo
その小さなサンプルデータでベンチマークを実行しましたか?もしそうなら、結果は信頼できない。 –
私もそう思った。大きなデータセットを試してみましょう。 – rmf