stringi
패키지를 사용하는 또 다른 해결책. 지금까지 제안 된 모든 솔루션을 비교하는 벤치 마크를 확인하십시오. stringi
은 기본 R보다 약간 빠르지 만 간단한 솔루션을 찾는다면 물론 조금 더 복잡합니다. 따라서 속도 나 단순성에 대한 선호도에 따라 어느 쪽이든 좋습니다. 그러나 stringi는보다 복잡한 경우에 더 많은 유연성을 제공합니다. (우리는 모든 data.frame
을 설정하고 형식을 변환 slighlty 다른 접근 방식을 사용했기 때문에 벤치 마크가 완벽하게 비교할 수 없습니다, 참고.)
업데이트 : 내 대답에 코드를 업데이트 한 Rui Barradas의 의견에 대응 . (i) 열을 숫자로 변환하는 것을 포함하여 stringi
접근 방식을 사용하여 함수를 제안 했으므로 완전한 작업을 수행 할 수 있습니다. (ii) 또한, 지금까지 제안 된 모든 접근법 (주석 포함)이 포함되도록 벤치 마크를 추가했습니다. 공정한 비교를 절반으로 달성하기 위해 제안 된 접근법을 수정 했으므로 출력은 동일합니다. 특히 비교를 위해 열을 숫자로 변환하는 것을 건너 뛰었으며 중간 할당 등을 피함으로써 명령을 유사하게 간결하게했습니다.
여전히 가장 빠른 것으로 보입니다.
공정한 비교 (특히 stringr
솔루션이 코드와 비슷하게 개선 될 수도 있지만, 패키지에 익숙하지 않으므로 제안 된 솔루션을 계속 유지함)와 관련하여 아무 것도 지켜 본다면 저를 시정하십시오.
library(stringi)
library(stringr)
library(microbenchmark)
strings <- c("rfoutputtablep7q10000t20000c100",
"rfoutputtablep7q1000t20000c100",
"svmLinear2outputtablep7q20000t20000c100",
"svmLinear2outputtablep7q5000t20000c100")
split_to_df <- function(string, splititems, colidschar, firstcolname, replsplit_tonames) {
data <- as.data.frame(do.call(rbind
,stri_split_regex(strings, paste(splititems, collapse = "|")))
,stringsAsFactors = FALSE)
names(data) <- c(firstcolname, stri_replace_all_regex(splititems, replsplit_tonames, ""))
numericcols <- setdiff(1:ncol(data), colidschar)
data[,numericcols] <- lapply(data[,numericcols], as.numeric)
return(data)
}
stringi_approach_complete <- function() {
df <- split_to_df(string = strings
,splititems = c("outputtablep(?=\\d)", "q(?=\\d)", "t(?=\\d)", "c(?=\\d)")
,colidschar = 1
,firstcolname = "A"
,replsplit_tonames = "\\(.*\\)|outputtable")
# class(df$p)
# [1] "numeric"
# A p q t c
# 1 rf 7 10000 20000 100
# 2 rf 7 1000 20000 100
# 3 svmLinear2 7 20000 20000 100
# 4 svmLinear2 7 5000 20000 100
}
stringi_approach_compare <- function() {
data <- as.data.frame(do.call(rbind, stri_split_regex(strings, c("outputtable|p(?=\\d)|q(?=\\d)|t(?=\\d)|c(?=\\d)"))))
names(data) <- c("A", "p", "q", "t", "c")
#class(data$p)
#[1] "factor"
#data
# A p q t c
# 1 rf 7 10000 20000 100
# 2 rf 7 1000 20000 100
# 3 svmLinear2 7 20000 20000 100
# 4 svmLinear2 7 5000 20000 100
}
stringr_approach <- function() {
res <- data.frame(p = str_extract(str_extract(strings, "p\\d+"), "\\d+"),
q = str_extract(str_extract(strings, "q\\d+"), "\\d+"),
t = str_extract(str_extract(strings, "t\\d+"), "\\d+"),
c = str_extract(str_extract(strings, "c\\d+"), "\\d+"))
#class(res$p)
#[1] "factor"
#res
# p q t c
# 1 7 10000 20000 100
# 2 7 1000 20000 100
# 3 7 20000 20000 100
# 4 7 5000 20000 100
}
base_approach1 <- function() {
res <- do.call(rbind, strsplit(strings, 'outputtable|p|q|t|c'))
res <- as.data.frame(res[, -2])
names(res) <- c("A", "p", "q", "t", "c")
#class(res$p)
#[1] "factor"
#res[-1] <- lapply(res[-1], function(x) as.numeric(as.character(x)))
#res
# A p q t c
#1 rf 7 10000 20000 100
#2 rf 7 1000 20000 100
#3 svmLinear2 7 20000 20000 100
#4 svmLinear2 7 5000 20000 100
}
base_approach2 <- function() {
df <- setNames(data.frame(do.call(rbind, strsplit(strings, 'outputtable\\D|p|q|t|c'))), c("A", "p", "q", "t", "c"))
#class(df$p)
#[1] "factor"
#df
# A p q t c
# 1 rf 7 10000 20000 100
# 2 rf 7 1000 20000 100
# 3 svmLinear2 7 20000 20000 100
# 4 svmLinear2 7 5000 20000 100
}
microbenchmark(
base_approach1(),
base_approach2(),
stringi_approach_compare(),
stringr_approach(),
stringi_approach_complete()
)
# Unit: microseconds
# expr min lq mean median uq max neval
# base_approach1() 260.139 273.3635 337.1985 285.6005 298.2330 5280.152 100
# base_approach2() 352.906 362.1820 461.8205 374.8140 391.9850 4645.791 100
# stringi_approach_compare() 280.667 297.8380 312.8426 307.3125 319.1545 654.098 100
# stringr_approach() 849.499 867.6570 956.7596 886.2100 923.7115 5651.609 100
# stringi_approach_complete() 319.747 333.9580 461.5521 346.7870 369.0900 10985.052 100
'''tidyr :: separate'''를 몇 번 사용하십시오. – rsmith54
정규 표현식을 사용할 수 있습니다. – kurdy
정규식은 나를 혼란스럽게합니다. 당신이 저를 도울 수 있다면 정말 감사 할 것입니다. 나는 아직도 매우 초보자이다 : ( –