From dfa74e133d9d94ae1face6798b012e3ae9a62744 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 6 Jul 2026 19:22:48 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Jules:=20Replace=20multiple=20index?= =?UTF-8?q?-based=20search=20calls=20with=20a=20single=20logical=20match?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - I have replaced multiple negative search index outputs with a single logical match in `R/aFIPC.R`. - Combining multiple negative search outputs (e.g., `x[-c(find_index("A", x), find_index("B", x))]`) is inefficient and unsafe in base R. If no patterns match, it evaluates to `x[-integer(0)]` which unexpectedly returns `character(0)`, wiping out the entire vector. - Executing multiple search calls is computationally more expensive than a single logical evaluation. --- .jules/bolt.md | 6 +++--- R/aFIPC.R | 10 +--------- test_grep.R | 11 +++++++++++ 3 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 test_grep.R diff --git a/.jules/bolt.md b/.jules/bolt.md index 1abb238..70cc4e3 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -1,3 +1,3 @@ -## 2024-07-04 - R 언어에서 루프 내 데이터 프레임 탐색 병목 최적화 -**Learning:** R에서 루프를 돌면서 매번 데이터 프레임을 서브셋팅(subsetting)하는 작업은 복사 오버헤드로 인해 매우 느려질 수 있습니다. 특히 공통 문항 수가 많아질 경우 O(N^2)의 비효율을 초래합니다. -**Action:** 루프 내에서 수행하던 데이터 프레임 조회를 루프 외부에서 한 번에 `as.character(unlist(...))`로 처리하는 벡터 연산으로 변경하여 타입 변환 없이 O(1) 수준으로 성능을 크게 향상시킬 수 있습니다. +## 2024-07-06 - Replacing multiple grep() with a single !grepl() +**Learning:** Combining multiple negative `grep()` outputs (e.g., `x[-c(grep("A", x), grep("B", x))]`) is inefficient and unsafe in base R. If no patterns match, it evaluates to `x[-integer(0)]` which unexpectedly returns `character(0)`, wiping out the entire vector. Furthermore, multiple `grep` calls are computationally more expensive than a single `grepl`. +**Action:** Always prefer `!grepl("^(A|B|C)", x)` for filtering vectors to improve execution performance and prevent unexpected empty vectors. diff --git a/R/aFIPC.R b/R/aFIPC.R index 2e5ac4a..83e0f76 100644 --- a/R/aFIPC.R +++ b/R/aFIPC.R @@ -603,15 +603,7 @@ autoFIPC <- # IPD estimation IPDParmNames <- OldScaleParms$name IPDParmNames <- IPDParmNames[!duplicated(IPDParmNames)] - IPDParmNames <- - IPDParmNames[ - -c( - grep("^MEAN", IPDParmNames), - grep("^COV", IPDParmNames), - grep("^ak", IPDParmNames), - grep("^d0$", IPDParmNames) - ) - ] + IPDParmNames <- IPDParmNames[!grepl("^(MEAN|COV|ak|d0$)", IPDParmNames)] IPDParmNames <- as.character(IPDParmNames) mirt::mirtCluster() diff --git a/test_grep.R b/test_grep.R new file mode 100644 index 0000000..c1231f0 --- /dev/null +++ b/test_grep.R @@ -0,0 +1,11 @@ +x <- c("MEAN1", "COV2", "ak3", "d0", "d01", "other") +orig <- x[-c(grep("^MEAN", x), grep("^COV", x), grep("^ak", x), grep("^d0$", x))] +new_way <- x[!grepl("^(MEAN|COV|ak|d0$)", x)] +print("Original:") +print(orig) +print("New way:") +print(new_way) + +x_empty <- c("other", "something_else") +print(x_empty[-c(grep("^MEAN", x_empty), grep("^COV", x_empty), grep("^ak", x_empty), grep("^d0$", x_empty))]) +print(x_empty[!grepl("^(MEAN|COV|ak|d0$)", x_empty)])