Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@
## 2026-06-30 - Preserve NA handling when removing factor conversions
**Learning:** `levels(as.factor(x))` excludes missing responses from the category count, so a faster replacement must not count `NA` as an extra response category.
**Action:** Keep `na.omit(unique(x))` rather than plain `unique(x)` in response-category comparisons.

## 2024-07-01 - Vectorized Data Frame String Extraction
**Learning:** In R, when vectorizing data frame subsetting to avoid `for` loops, calling `as.character()` directly on a multi-column subset (e.g., `as.character(df[1, cols])`) stringifies the underlying list structure (e.g. `c("list(a = 1)", "list(b = 2)")`) rather than the elements themselves.
**Action:** Always apply `unlist()` first (e.g., `as.character(unlist(df[1, cols]))`) to safely flatten the row into a vector while preserving element-specific string conversion for types like factors.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

## [Unreleased]
### 성능 개선 (Performance)
- `R/aFIPC.R` 내 공통 문항명 추출 과정을 `for` 루프에서 `as.character(unlist(...))` 벡터 연산으로 변경하여 실행 속도를 최적화했습니다. (⚡ Bolt)
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export(autoFIPC)
export(surveyFA)
import(mirt)
importFrom(stats,factanal)
importFrom("stats", "na.omit")
12 changes: 4 additions & 8 deletions R/aFIPC.R
Original file line number Diff line number Diff line change
Expand Up @@ -688,16 +688,12 @@ autoFIPC <-
print(modIPD_DIF)
print(CommonItemList_NOIPD)

# [Bolt] ⚡ 성능 최적화: for 루프를 사용한 순차적 컬럼명 추출을 벡터화 연산으로 변경하여
# R의 data.frame subsetting 병목을 제거하고 O(1) 수준으로 성능 개선
Comment on lines +691 to +692
ActualoldFormCommonItem <-
vector(length = length(CommonItemList_NOIPD))
as.character(unlist(IPDItemList[CommonItemList_NOIPD][1, ]))
ActualnewFormCommonItem <-
vector(length = length(CommonItemList_NOIPD))
for (i in 1:length(CommonItemList_NOIPD)) {
ActualoldFormCommonItem[i] <-
as.character(IPDItemList[CommonItemList_NOIPD][1, i])
ActualnewFormCommonItem[i] <-
as.character(IPDItemList[CommonItemList_NOIPD][2, i])
}
as.character(unlist(IPDItemList[CommonItemList_NOIPD][2, ]))
Comment on lines 693 to +696

message('ActualoldFormCommonItem: ', ActualoldFormCommonItem)
message('ActualnewFormCommonItem: ', ActualnewFormCommonItem)
Expand Down
15 changes: 15 additions & 0 deletions tests/testthat/test-vectorize.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
test_that("Vectorized name extraction works correctly", {
IPDItemList <- data.frame(
item1 = c("old_item1", "new_item1"),
item2 = c("old_item2", "new_item2"),
stringsAsFactors = FALSE
)

CommonItemList_NOIPD <- c("item1", "item2")

old_names <- as.character(unlist(IPDItemList[CommonItemList_NOIPD][1, ]))
new_names <- as.character(unlist(IPDItemList[CommonItemList_NOIPD][2, ]))

expect_equal(old_names, c("old_item1", "old_item2"))
expect_equal(new_names, c("new_item1", "new_item2"))
})
Comment on lines +1 to +15
Loading