2016-10-20 3 views
0

クラス名と対応するフォルトを含むCSVファイルに次の種類のデータセット(ds1)があります。私は、Rスクリプトを使用して、2つのフォールト数のデータからパッケージ名を抽出またはフィルタリングするつもりです。Rスクリプトを使用して完全に定義されたクラス名からパッケージ名を抽出する

Class        Faults 

org.apache.tools.ant.taskdefs.Definer 2 
org.apache.tools.ant.taskdefs.Definer 2 
org.apache.tools.ant.taskdefs.Delete 1 
org.apache.tools.ant.taskdefs.Deltree 2 
org.apache.tools.ant.taskdefs.DependSet 2 
org.apache.tools.ant.taskdefs.DependSet 2 
org.apache.tools.ant.taskdefs.DependSet 2 
org.apache.tools.ant.taskdefs.Ear 2 
org.apache.tools.ant.taskdefs.Ear 2 
org.apache.tools.ant.taskdefs.Echo 1 
org.apache.tools.ant.Exec 2 
org.apache.tools.ant.Exec 2 

私はそれが

dschanged<- subset(ds1, grep("/^([^\\.]+)/", class) & Faults==2) 

は技術的には、私は最後のドットの前の文字列を引っ張って適切な正規表現を必要とする(。)出力以下の生成に所望の出力を生成しません、コードを次のよう書かれていますが、しています。

org.apache.tools.ant.taskdefs  2 
org.apache.tools.ant.taskdefs  2 
org.apache.tools.ant.taskdefs  2 
org.apache.tools.ant.taskdefs  2 
org.apache.tools.ant.taskdefs  2 
org.apache.tools.ant.taskdefs  2 
org.apache.tools.ant.taskdefs  2 
org.apache.tools.ant.taskdefs  2 
org.apache.tools.ant    2 
org.apache.tools.ant    2 
+2

'greplはもっと適切でしょうか? – r2evans

+0

'grepl'を使って解決できますか? –

+0

'' /^([^\\.]+)/ ''には深刻な問題が1つあります:R正規表現関数では使用しない正規表現の区切り文字 '/'を使用しています。さらに、文字クラスで '.'をエスケープすると、PCREのみの互換表現になります(もはやTRE互換ではありません)。しかし、最後のドットの前の文字列を取得するには、 '' ^(*)\\。 "'(PC1) \。) "'( 'perl = TRUE'で)。 –

答えて

1

grep(およびgrepl)は、このために不適切である:あなたはテキストコンテンツに基づいてフィルタリングされていません。あなたは(a)Faultsに基づいてフィルタリングしており、(b)Classにテキストを変更しています。

あなたのデータ:Faults

ds1 <- structure(list(Class = c("org.apache.tools.ant.taskdefs.Definer", "org.apache.tools.ant.taskdefs.Definer", "org.apache.tools.ant.taskdefs.Delete", "org.apache.tools.ant.taskdefs.Deltree", "org.apache.tools.ant.taskdefs.DependSet", "org.apache.tools.ant.taskdefs.DependSet", "org.apache.tools.ant.taskdefs.DependSet", "org.apache.tools.ant.taskdefs.Ear", "org.apache.tools.ant.taskdefs.Ear", "org.apache.tools.ant.taskdefs.Echo", "org.apache.tools.ant.Exec", "org.apache.tools.ant.Exec"), 
         Faults = c(2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L)), 
       .Names = c("Class", "Faults"), class = "data.frame", row.names = c(NA, -12L)) 

フィルター(あなたはすでにこれを持っていました)。これらの2つのコマンドのうちの1つだけが必要です。両方とも同じことを行います。主な違いは読みやすさ(個人的な好み)とパフォーマンスです(2番目のものは、この場合、約35%の時間がかかりますが、どちらもマイクロ秒単位で測定されるため、競争するのは愚かなようです)。

ds2 <- subset(ds1, Faults == 2) 
ds2 <- ds1[ds1$Faults == 2,] 

更新Classは最後の単語(ドット)を削除するには:

ds2$Class <- gsub("\\.[^.]*$", "", ds2$Class) 
ds2 
#       Class Faults 
# 1 org.apache.tools.ant.taskdefs  2 
# 2 org.apache.tools.ant.taskdefs  2 
# 4 org.apache.tools.ant.taskdefs  2 
# 5 org.apache.tools.ant.taskdefs  2 
# 6 org.apache.tools.ant.taskdefs  2 
# 7 org.apache.tools.ant.taskdefs  2 
# 8 org.apache.tools.ant.taskdefs  2 
# 9 org.apache.tools.ant.taskdefs  2 
# 11   org.apache.tools.ant  2 
# 12   org.apache.tools.ant  2 

注:これはまた、代わりにgsubsubで行うことができますが、後者は、私の最も以来初めて、リーチ私の使用は、大規模で繰り返しの正規表現を扱う。 (?subから)

'sub' and 'gsub' perform replacement of the first and all matches respectively

:2の間の主要な(?のみ)の違いは、ということです。

両方ともフィルタリングと1つのコマンドでの変更(おそらくdata.tableはありますがわかりません)。(それがmagrittrを使用しています)、ここで読むと、(パフォーマンスの潜在的なコストで)適応するために、多くの人々は非常に簡単です主張dplyrを使用して、一つだ@のegnhaのソリューションと同様に

library(dplyr) 
ds2 <- ds1 %>% 
    filter(Faults == 2) %>% 
    mutate(Class = gsub("\\.[^.]*$", "", Class)) 

私が述べたので、パフォーマンスは、ここでの比較です:レコードの

microbenchmark(indexing = { ds2 <- ds1[ds1$Faults == 2,]; ds2$Class <- gsub("\\.[^.]*$", "", ds2$Class) }, 
       subset = { ds2 <- subset(ds1, Faults == 2) ; ds2$Class <- gsub("\\.[^.]*$", "", ds2$Class) }, 
       dplyr = { ds1 %>% filter(Faults == 2) %>% mutate(Class = gsub("\\.[^.]*$", "", Class)) }) 
# Unit: microseconds 
#  expr  min  lq  mean median  uq  max neval 
# indexing 71.841 87.7045 109.4496 104.2975 120.7075 269.493 100 
# subset 102.473 115.6020 147.0108 139.1230 165.5620 287.726 100 
#  dplyr 1067.030 1156.3745 1323.1174 1225.4805 1351.2920 4270.308 100 

は、このように使用dplyrは、他の方法と比較して、多くの場合、この速度に乏しいではありません。一般的にはではありませんが、それよりもはるかに遅いものではありません。

+0

ありがとう@ r2evans –

+0

それは私のために働いた –

+0

@ r2evans - 良いベンチマーク。この場合、私はdplyrが非常に遅くなるとは思わなかったでしょう。なぜ洞察? – egnha

0

はまた、任意の派手な正規表現のせずにこれを行うことができます。そして、すべてが、最後の部分文字列をドットペースト、ドット上の各Class文字列を分割します。

library(magrittr) # Provides pipe operator `%>%` 

dschanged <- subset(ds1, Faults == 2) 
dschanged$Class <- dschanged$Class %>% 
        strsplit(split = "[.]") %>% 
        sapply(function(x) head(x, -1L) %>% paste(collapse = ".")) 

ドットのない文字列は空の文字列に変換されます。 @ r2evansによって提案された解決策よりかなり遅いです。

+0

実際には、ソリューションに非ベースライブラリを含める必要があります。誰もがこれが 'magrittr'を使っているのを知るのに十分なほど流暢ではありません。 – r2evans

+0

@ r2evans - 私はそれを見落としていた、ありがとう。変更が行われました。 – egnha

0

私はあなたのクラス名に基づいてフィルタリングを探しているとは思いません。 2ステップで実行します。

# Filter 
dschanged <- ds1[ds1$Faults == 2,] 
# Extract package name 
dschanged$class <- sub('(.*)[.](.*)','\\1',dschanged$class) 
関連する問題