diff --git a/.jules/bolt.md b/.jules/bolt.md index 1abb238..2c01aa9 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -1,3 +1,4 @@ -## 2024-07-04 - R 언어에서 루프 내 데이터 프레임 탐색 병목 최적화 -**Learning:** R에서 루프를 돌면서 매번 데이터 프레임을 서브셋팅(subsetting)하는 작업은 복사 오버헤드로 인해 매우 느려질 수 있습니다. 특히 공통 문항 수가 많아질 경우 O(N^2)의 비효율을 초래합니다. -**Action:** 루프 내에서 수행하던 데이터 프레임 조회를 루프 외부에서 한 번에 `as.character(unlist(...))`로 처리하는 벡터 연산으로 변경하여 타입 변환 없이 O(1) 수준으로 성능을 크게 향상시킬 수 있습니다. +## 2024-07-05 - Optimize Base R Vector Subsetting +**Learning:** Combining multiple `grep()` queries (e.g. `-c(grep("^A", x), grep("^B", x))`) is not only 2-3x slower than a single `grepl()` with regex OR (`|`) or direct equality comparisons, but it also carries a critical safety risk in base R. If none of the strings match any regex, all `grep()` calls return `integer(0)`. Concatenating them with `c()` yields `integer(0)`, and subsetting `x[-integer(0)]` returns `character(0)` instead of the original unmodified vector `x`, which can inadvertently wipe out data in production code. + +**Action:** Always prefer `!grepl("^(A|B|C)", x)` over negative `c()` subsetting of multiple `grep` outputs when removing multiple patterns from a vector in R. For exact string matches, prefer `x != "value"` or `!(x %in% c(...))` over regexes. \ No newline at end of file diff --git a/R/aFIPC.R b/R/aFIPC.R index 2e5ac4a..8b39e9d 100644 --- a/R/aFIPC.R +++ b/R/aFIPC.R @@ -604,14 +604,7 @@ autoFIPC <- IPDParmNames <- OldScaleParms$name IPDParmNames <- IPDParmNames[!duplicated(IPDParmNames)] IPDParmNames <- - IPDParmNames[ - -c( - grep("^MEAN", IPDParmNames), - grep("^COV", IPDParmNames), - grep("^ak", IPDParmNames), - grep("^d0$", IPDParmNames) - ) - ] + IPDParmNames[!grepl("^(MEAN|COV|ak)", IPDParmNames) & IPDParmNames != "d0"] IPDParmNames <- as.character(IPDParmNames) mirt::mirtCluster()