Skip to content

Commit 96a229d

Browse files
author
martiki9
committed
make benefits a stub article for now
1 parent 634f13a commit 96a229d

2 files changed

Lines changed: 81 additions & 39 deletions

File tree

white-paper/benefits.qmd

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,4 @@
22

33
## Introduction
44

5-
Statistical programmers in the pharmaceutical industry operate in a highly regulated environment where validated, reproducible analysis is paramount. For several years, the standard workflow has revolved around statistical computing environments managed through shared network drives, strict naming conventions, and manual version control practices (saving files with incremental version numbers or descriptive suffixes before archiving) or with regular server backups. These habits, while informal, have been deeply embedded in day-to-day practice and have served as the de facto audit trail in many organizations.
6-
7-
Introducing Git into this context presents a unique set of challenges that go beyond mere tool adoption. It relies on notions such as sub-branches linked to a main branch, commits, remote repositories and merges, that can be difficult to adopt for teams used to work in other environments. The learning curve can be difficult and requires to embrace a more collaborative and transparent workflow.
8-
9-
Furthermore, the regulatory framework of the pharmaceutical industry is strict. Any change management system touching analysis code or submission-relevant outputs must be set in a GxP environment. Git must be used in a way that ensures theses compliances (traceability, audit, etc).
10-
11-
Organizational culture also plays a significant role. Statistical programmers often work independently or in small teams with well-established personal workflows. Moving to a Git focused workflow requires not only technical training, but to being open to new mindsets and ways of working.
12-
13-
## Benefits of Git for statistical programmers
14-
15-
One important lesson from companies that have already experienced the transition to using Git is that, because Git can be a challenging technology to adopt at first, it can be easy to lose sight as to why this change is being made.
16-
17-
To combat this difficulty, we recommend highlighting early and often the benefits of adopting Git in practice. These are covered in more detail in the chapter
18-
19-
## Prepare basic documentation
20-
21-
::: callout-caution
22-
*Git documentation online can be realy long and complex. Write down the basics at firs (main, sub-branches, commits, push, pull request, merge).*
23-
:::
24-
25-
## Introduce tools
26-
27-
::: callout-caution
28-
*Do not talk a lot about in line Git commands and show one or two software that can help (GitHub Desktop, VSCode, etc). Give command line equivalent to each actions (commit, push, etc).*
29-
*For VSCode, since a lot of people are using SAS, RStudio or Positron, explain how to use it only for Git (or how to switch).*
30-
:::
31-
32-
## Make people use Git as a training
33-
34-
::: callout-caution
35-
*Do not demonstrate, make people use Git with small examples: make an update on a file, review a PR, read commit history, etc.*
36-
:::
37-
38-
39-
40-
#Benefits
41-
42-
## Introduction
43-
445
This chapter aims to include at a high level some benefits for using Git in clinical development.

white-paper/test.r

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
floatinginequality <- function(x, y, inequality, ...){
2+
compare <- isTRUE(all.equal(x,y, ...))
3+
if (compare){
4+
if (inequality %in% c("==", "<=", ">=")) return(TRUE)
5+
return(FALSE)
6+
}
7+
if (inequality == "==") return(FALSE)
8+
9+
if (inequality %in% c("<=", "<")) return(x<y)
10+
11+
return(x>y)
12+
13+
}
14+
15+
# Version 2: accepts an operator symbol instead of a string
16+
# Infix operators must be wrapped in backticks: `==`, `<=`, `>=`, `<`, `>`
17+
# Usage: floatinginequality_op(0.1+0.2, 0.3, `==`)
18+
floatinginequality_op <- function(x, y, inequality, ...) {
19+
op_str <- deparse(substitute(inequality))
20+
floatinginequality(x, y, op_str, ...)
21+
}
22+
23+
# Version 3: accepts a full expression, e.g. floatinginequality_expr(0.9 > 3*0.3)
24+
# Self-contained: captures expression unevaluated, extracts LHS, operator, and RHS,
25+
# then applies floating-point-safe comparison logic directly.
26+
floatinginequality_expr <- function(expr, ...) {
27+
e <- substitute(expr)
28+
if (!is.call(e) || length(e) != 3) {
29+
stop("expr must be a binary comparison expression, e.g. 0.9 > 3*0.3")
30+
}
31+
op <- deparse(e[[1]])
32+
x <- eval(e[[2]], parent.frame())
33+
y <- eval(e[[3]], parent.frame())
34+
35+
if (isTRUE(all.equal(x, y, ...))) {
36+
return(op %in% c("==", "<=", ">="))
37+
}
38+
if (op == "==") return(FALSE)
39+
if (op %in% c("<=", "<")) return(x < y)
40+
return(x > y)
41+
}
42+
43+
# Tests
44+
cat("--- Floating point equality (would fail with naive ==) ---\n")
45+
cat("(0.1+0.2 == 0.3) :", floatinginequality_expr(0.1+0.2 == 0.3), "\n") # TRUE
46+
cat("(0.9 == 3*0.3) :", floatinginequality_expr(0.9 == 3*0.3), "\n") # TRUE
47+
48+
cat("\n--- Strict inequality on near-equal values ---\n")
49+
cat("(0.1+0.2 < 0.3) :", floatinginequality_expr(0.1+0.2 < 0.3), "\n") # FALSE
50+
cat("(0.1+0.2 > 0.3) :", floatinginequality_expr(0.1+0.2 > 0.3), "\n") # FALSE
51+
cat("(0.1+0.2 <= 0.3) :", floatinginequality_expr(0.1+0.2 <= 0.3), "\n") # TRUE
52+
cat("(0.1+0.2 >= 0.3) :", floatinginequality_expr(0.1+0.2 >= 0.3), "\n") # TRUE
53+
cat("(0.9 > 3*0.3) :", floatinginequality_expr(0.9 > 3*0.3), "\n") # FALSE
54+
cat("(0.9 >= 3*0.3) :", floatinginequality_expr(0.9 >= 3*0.3), "\n") # TRUE
55+
56+
cat("\n--- Clearly unequal values ---\n")
57+
cat("(1 < 2) :", floatinginequality_expr(1 < 2), "\n") # TRUE
58+
cat("(1 > 2) :", floatinginequality_expr(1 > 2), "\n") # FALSE
59+
cat("(1 == 2) :", floatinginequality_expr(1 == 2), "\n") # FALSE
60+
cat("(1 <= 2) :", floatinginequality_expr(1 <= 2), "\n") # TRUE
61+
cat("(2 >= 1) :", floatinginequality_expr(2 >= 1), "\n") # TRUE
62+
63+
64+
floatinginequality <- function(expr, ...) {
65+
e <- substitute(expr)
66+
if (!is.call(e) || length(e) != 3) {
67+
stop("expr must be a binary comparison expression, e.g. 0.9 > 3*0.3")
68+
}
69+
op <- deparse(e[[1]])
70+
x <- eval(e[[2]], parent.frame())
71+
y <- eval(e[[3]], parent.frame())
72+
73+
if (isTRUE(all.equal(x, y, ...))) {
74+
return(op %in% c("==", "<=", ">="))
75+
}
76+
if (op == "==") return(FALSE)
77+
if (op %in% c("<=", "<")) return(x < y)
78+
return(x > y)
79+
}
80+
floatinginequality(0.9 >= 0.3*3)
81+
floatinginequality(0.9 ==0.3*3)

0 commit comments

Comments
 (0)