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
3 changes: 3 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@
^\.jules(/.*)?$
^\.trivyignore\.yaml$
^trivy\.yaml$
^\.semgrepignore$
^packrat$
packrat/
3 changes: 3 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
## 2025-02-12 - R ์–ธ์–ด์—์„œ ๋ฐ˜๋ณต์ ์ธ mirt ๋ชจ๋ธ ์ƒ์„ฑ ์‹œ ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„ ๋ถ€๋ถ„์ง‘ํ•ฉ ์ถ”์ถœ ์ตœ์ ํ™”
**Learning:** R์—์„œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„์˜ ํŠน์ • ์—ด์„ ์ถ”์ถœํ•˜๋Š” ์ž‘์—…(`df[cols]`)์€ O(N)์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ๋ฅผ ์ˆ˜๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค. `autoFIPC`์—์„œ `mirt` ๋ชจ๋ธ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ํ˜ธ์ถœํ•˜๋Š” ๊ณผ์ • ์ค‘์— `newformXDataK[colnames(newFormModel@Data$data)]` ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋ณตํ•ด์„œ ์‚ฌ์šฉ๋˜์—ˆ๊ณ , ์‹ฌ์ง€์–ด `ncol()`์„ ์œ„ํ•ด ๋‹จ์ˆœํžˆ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•  ๋•Œ๋„ ์‚ฌ์šฉ๋˜์–ด ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ณผ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ดˆ๋ž˜ํ–ˆ์Šต๋‹ˆ๋‹ค.
**Action:** ์กฐ๊ฑด๋ฌธ์ด๋‚˜ ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€์—์„œ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„ ๋ถ€๋ถ„์ง‘ํ•ฉ ์—ฐ์‚ฐ์ด ๋ฐ˜๋ณต๋˜์ง€ ์•Š๋„๋ก ์™ธ๋ถ€์—์„œ ํ•œ ๋ฒˆ๋งŒ `linkedFormData <- newformXDataK[colnames(newFormModel@Data$data)]`๋กœ ์บ์‹ฑ(caching)ํ•œ ๋’ค, `ncol(linkedFormData)`์™€ `data = linkedFormData` ํ˜•ํƒœ๋กœ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ์™€ O(N) ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋ฐฉ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
## 2024-05-18 - Fast Dataframe Assignment in R
**Learning:** In base R, 2D dataframe subsetting assignments (e.g. `df[idx, "col"] <- val`) suffer from significant `[<-.data.frame` method dispatch and dimensionality checking overhead.
**Action:** Replace them with direct vector assignments (e.g. `df$col[idx] <- val`) to bypass the overhead for measurable performance gains in tight loops or large datasets.
48 changes: 24 additions & 24 deletions R/aFIPC.R
Original file line number Diff line number Diff line change
Expand Up @@ -598,15 +598,15 @@ autoFIPC <-
# Preserve mirt's structural estimability flags. Forcing every row TRUE
# frees boundary parameters such as 2PL g/u and makes the Hessian unstable.

NewScaleParms[NewScaleParms$item == 'GROUP', "est"] <- FALSE
OldScaleParms[OldScaleParms$item == 'GROUP', "est"] <- FALSE
NewScaleParms$est[NewScaleParms$item == 'GROUP'] <- FALSE
OldScaleParms$est[OldScaleParms$item == 'GROUP'] <- FALSE

NewScaleParms[NewScaleParms$name == "COV_11", "est"] <- TRUE
OldScaleParms[OldScaleParms$name == "COV_11", "est"] <- TRUE
NewScaleParms$est[NewScaleParms$name == "COV_11"] <- TRUE
OldScaleParms$est[OldScaleParms$name == "COV_11"] <- TRUE

if (itemtype == 'Rasch') {
NewScaleParms[NewScaleParms$name == "a1", "est"] <- FALSE
OldScaleParms[OldScaleParms$name == "a1", "est"] <- FALSE
NewScaleParms$est[NewScaleParms$name == "a1"] <- FALSE
OldScaleParms$est[OldScaleParms$name == "a1"] <- FALSE
}

#IPD
Expand Down Expand Up @@ -786,14 +786,14 @@ autoFIPC <-
oldIdx <- oldScaleParmsItemIdxCache[[oldFormItemStr]]

# โšก Bolt: Remove unnecessary paste0() array string generation overhead
message(' Newform Parms: ', paste(NewScaleParms[newIdx, "value"], collapse = ' '))
message(' Oldform Parms: ', paste(OldScaleParms[oldIdx, "value"], collapse = ' '))
message(' Newform Parms: ', paste(NewScaleParms$value[newIdx], collapse = ' '))
message(' Oldform Parms: ', paste(OldScaleParms$value[oldIdx], collapse = ' '))

NewScaleParms[newIdx, "value"] <-
OldScaleParms[oldIdx, "value"]
message(' Linkedform Parms: ', paste(NewScaleParms[newIdx, "value"], collapse = ' '), '\n')
NewScaleParms$value[newIdx] <-
OldScaleParms$value[oldIdx]
message(' Linkedform Parms: ', paste(NewScaleParms$value[newIdx], collapse = ' '), '\n')

NewScaleParms[newIdx, "est"] <-
NewScaleParms$est[newIdx] <-
FALSE
} else {
message(
Expand All @@ -813,17 +813,17 @@ autoFIPC <-
newBetaIdx <- NewScaleParms$item == 'BETA'
oldBetaIdx <- OldScaleParms$item == 'BETA'

NewScaleParms[newBetaIdx, "value"] <-
OldScaleParms[oldBetaIdx, "value"]
NewScaleParms[newBetaIdx, "est"] <-
NewScaleParms$value[newBetaIdx] <-
OldScaleParms$value[oldBetaIdx]
NewScaleParms$est[newBetaIdx] <-
FALSE

message('applying BETA parameter as linking')

message(
' Linkedform Parms: ',
paste0(
NewScaleParms[newBetaIdx, "value"],
NewScaleParms$value[newBetaIdx],
' '
),
'\n'
Expand Down Expand Up @@ -858,13 +858,13 @@ autoFIPC <-
new_mean11_idx <- NewScaleParms$name == "MEAN_11"
old_mean11_idx <- OldScaleParms$name == "MEAN_11"

NewScaleParms[new_cov11_idx, "est"] <- FALSE
OldScaleParms[old_cov11_idx, "est"] <- FALSE
NewScaleParms[new_mean11_idx, "est"] <- FALSE
OldScaleParms[old_mean11_idx, "est"] <- FALSE
NewScaleParms$est[new_cov11_idx] <- FALSE
OldScaleParms$est[old_cov11_idx] <- FALSE
NewScaleParms$est[new_mean11_idx] <- FALSE
OldScaleParms$est[old_mean11_idx] <- FALSE

NewScaleParms[new_cov11_idx, "value"] <- 1
OldScaleParms[old_mean11_idx, "value"] <- 0
NewScaleParms$value[new_cov11_idx] <- 1
OldScaleParms$value[old_mean11_idx] <- 0
}
if (freeMEAN == T) {
LinkedModelSyntax <-
Expand All @@ -875,8 +875,8 @@ autoFIPC <-
'MEAN = F1'
))

NewScaleParms[NewScaleParms$name == "MEAN_1", "est"] <- TRUE
OldScaleParms[OldScaleParms$name == "MEAN_1", "est"] <- TRUE
NewScaleParms$est[NewScaleParms$name == "MEAN_1"] <- TRUE
OldScaleParms$est[OldScaleParms$name == "MEAN_1"] <- TRUE
} else {
LinkedModelSyntax <-
mirt::mirt.model(paste0(
Expand Down
18 changes: 18 additions & 0 deletions aFIPC.Rcheck/00_pkg_src/aFIPC/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Package: aFIPC
Type: Package
Title: Automated Fixed Item Parameter Linking
Version: 0.1.0
Author: Seongho Bae [aut, cre]
Maintainer: Seongho Bae <seongho@kw.ac.kr>
Authors@R: person(given = "Seongho", family = "Bae", role = c("aut", "cre"),
email = "seongho@kw.ac.kr")
Description: Automates fixed item parameter linking for test linking under
the item response theory paradigm using mirt package estimates.
License: GPL-3 | file LICENSE
Imports: mirt, methods
Suggests: testthat (>= 3.0.0)
Encoding: UTF-8
Config/testthat/edition: 3
Config/roxygen2/version: 8.0.0
NeedsCompilation: no
Packaged: 2026-07-31 16:50:43 UTC; jules

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿ“ Maintainability & Code Quality | ๐ŸŸ  Major | โšก Quick win

aFIPC.Rcheck/ ์ƒ์„ฑ๋ฌผ์„ PR์—์„œ ์ œ๊ฑฐํ•˜์„ธ์š”.

Line 18์˜ Packaged ํ•„๋“œ๋Š” ์ƒ์„ฑ๋œ ํŒจํ‚ค์ง€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. ๋™์ผํ•œ aFIPC.Rcheck/ ํŠธ๋ฆฌ์—๋Š” Built, INDEX, NAMESPACE, lazy-load ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ํ•จ๊ป˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅ์†Œ์— ํฌํ•จํ•˜๋ฉด ์†Œ์Šค ์ •๋ณธ๊ณผ ์ƒ์„ฑ ์‹œ์ ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ๋ถ„๋ฆฌ๋ฉ๋‹ˆ๋‹ค. R CMD build๊ฐ€ ์ค‘์ฒฉ๋œ ํŒจํ‚ค์ง€ ์‚ฐ์ถœ๋ฌผ์„ ๋‹ค์‹œ ํฌํ•จํ•  ์œ„ํ—˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

aFIPC.Rcheck/๋ฅผ PR์—์„œ ์ œ๊ฑฐํ•˜๊ณ  ์ €์žฅ์†Œ์˜ .gitignore์— *.Rcheck/๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”. .Rbuildignore๋Š” Git์—์„œ ์ด๋ฏธ ์ถ”์ ๋œ ํŒŒ์ผ์„ ์ œ๊ฑฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๐Ÿค– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@aFIPC.Rcheck/00_pkg_src/aFIPC/DESCRIPTION` at line 18, Remove the generated
aFIPC.Rcheck/ tree, including its Packaged metadata and related build artifacts,
from the repository, then add *.Rcheck/ to the repositoryโ€™s .gitignore so future
check outputs remain untracked. Do not rely on .Rbuildignore for this cleanup.

2 changes: 2 additions & 0 deletions aFIPC.Rcheck/00_pkg_src/aFIPC/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
YEAR: 2026
COPYRIGHT HOLDER: Seongho Bae
5 changes: 5 additions & 0 deletions aFIPC.Rcheck/00_pkg_src/aFIPC/NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Generated by roxygen2: do not edit by hand

export(autoFIPC)
export(surveyFA)
import(mirt)
Loading
Loading