2016-10-20 4 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

''/^([^\\.]+)/''에는 심각한 문제가 있습니다 : R 정규 표현식 함수에서 사용해서는 안되는 정규 표현식 분리 문자'/'를 사용하고 있습니다. 게다가 캐릭터 클래스에서'.'을 벗어나면, PCRE 전용 호환 표현식이됩니다 (더 이상 TRE와 호환되지 않습니다). 그러나 마지막 점 앞에 문자열을 가져 오려면' "^ (* *) \\."'(1 번 그룹 안에 캡처 된 값이 있어야합니다.) 또는 PCRE 하나 "'. * (? = \ \.) "('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)) 

필터 (당신은 이미이 있었다). 이 두 명령 중 하나만 필요합니다. 둘 다 똑같은 일을합니다. 주요 차이점은 가독성 (개인 선호도)과 성능 (두 번째 것은 약 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와 함께 할 수 있지만, 후자는 내 대부분의 이후 처음 도달 내 사용 큰 및 반복 regexes 처리합니다. 둘 사이의 가장 큰 (? 만) 차이는 :

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

(?sub부터).

두 도구 모두 알고 있습니다. 단일 명령으로 필터링하고 변경합니다 (아마도 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)