df = read.csv("Bone data.csv")
dim(df)
## [1] 2162 9
head(df)
## id sex age weight height prior.fx fnbmd smoking fx
## 1 1 Male 73 98 175 0 1.08 1 0
## 2 2 Female 68 72 166 0 0.97 0 0
## 3 3 Male 68 87 184 0 1.01 0 0
## 4 4 Female 62 72 173 0 0.84 1 0
## 5 5 Male 61 72 173 0 0.81 1 0
## 6 6 Female 76 57 156 0 0.74 0 0
summary(df)
## id sex age weight
## Min. : 1.0 Length:2162 Min. :57.00 Min. : 34.00
## 1st Qu.: 545.2 Class :character 1st Qu.:65.00 1st Qu.: 60.00
## Median :1093.5 Mode :character Median :69.00 Median : 69.00
## Mean :1094.7 Mean :70.65 Mean : 70.14
## 3rd Qu.:1639.8 3rd Qu.:75.00 3rd Qu.: 79.00
## Max. :2216.0 Max. :94.00 Max. :133.00
## NA's :1
## height prior.fx fnbmd smoking
## Min. :136.0 Min. :0.0000 Min. :0.2800 Min. :0.0000
## 1st Qu.:158.0 1st Qu.:0.0000 1st Qu.:0.7300 1st Qu.:0.0000
## Median :164.0 Median :0.0000 Median :0.8200 Median :0.0000
## Mean :164.9 Mean :0.1554 Mean :0.8287 Mean :0.4251
## 3rd Qu.:171.0 3rd Qu.:0.0000 3rd Qu.:0.9300 3rd Qu.:1.0000
## Max. :196.0 Max. :1.0000 Max. :1.5100 Max. :1.0000
## NA's :40
## fx
## Min. :0.0000
## 1st Qu.:0.0000
## Median :0.0000
## Mean :0.2521
## 3rd Qu.:1.0000
## Max. :1.0000
##
# Kiểm tra nhanh
str(df)
## 'data.frame': 2162 obs. of 9 variables:
## $ id : int 1 2 3 4 5 6 7 8 9 10 ...
## $ sex : chr "Male" "Female" "Male" "Female" ...
## $ age : int 73 68 68 62 61 76 63 64 76 64 ...
## $ weight : int 98 72 87 72 72 57 97 85 48 89 ...
## $ height : int 175 166 184 173 173 156 173 167 153 166 ...
## $ prior.fx: int 0 0 0 0 0 0 0 0 0 0 ...
## $ fnbmd : num 1.08 0.97 1.01 0.84 0.81 0.74 1.01 0.86 0.65 0.98 ...
## $ smoking : int 1 0 0 1 1 0 1 0 0 0 ...
## $ fx : int 0 0 0 0 0 0 0 0 0 0 ...
# Vẽ histogram
hist(df$fnbmd,
main = "Histogram of Femoral Neck BMD",
xlab = "Femoral neck BMD (g/cm2)",
col = "blue",
border = "white")
library(lessR);
##
## lessR 4.5 feedback: gerbing@pdx.edu
## --------------------------------------------------------------
## > d <- Read("") Read data file, many formats available, e.g., Excel
## d is the default data frame, data= in analysis routines optional
##
## Many examples of reading, writing, and manipulating data, graphics,
## testing means and proportions, regression, factor analysis,
## customization, forecasting, and aggregation to pivot tables.
## Enter: browseVignettes("lessR")
##
## View lessR updates, now including modern time series forecasting
## and many, new Plotly interactive visualizations output. Most
## visualization functions are now reorganized to three functions:
## Chart(): type="bar", "pie", "radar", "bubble", "treemap", "icicle"
## X(): type="histogram", "density", "vbs" and more
## XY(): type="scatter" for a scatterplot, or "contour", "smooth"
## Most previous function calls still work, such as:
## BarChart(), Histogram, and Plot().
## Enter: news(package="lessR"), or ?Chart, ?X, or ?XY
## There is also Flows() for Sankey flow diagrams, see ?Flows
##
## Interactive data analysis for constructing visualizations.
## Enter: interact()
library(table1)
##
## Attaching package: 'table1'
## The following object is masked from 'package:lessR':
##
## label
## The following objects are masked from 'package:base':
##
## units, units<-
ttest(fnbmd ~ sex, data = df)
##
## Compare fnbmd across sex with levels Male and Female
## Grouping Variable: sex
## Response Variable: fnbmd
##
##
## ------ Describe ------
##
## fnbmd for sex Male: n.miss = 23, n = 822, mean = 0.910, sd = 0.153
## fnbmd for sex Female: n.miss = 17, n = 1300, mean = 0.778, sd = 0.132
##
## Mean Difference of fnbmd: 0.132
##
## Weighted Average Standard Deviation: 0.141
##
##
## ------ Assumptions ------
##
## Note: These hypothesis tests can perform poorly, and the
## t-test is typically robust to violations of assumptions.
## Use as heuristic guides instead of interpreting literally.
##
## Null hypothesis, for each group, is a normal distribution of fnbmd.
## Group Male: Sample mean assumed normal because n > 30, so no test needed.
## Group Female: Sample mean assumed normal because n > 30, so no test needed.
##
## Null hypothesis is equal variances of fnbmd, homogeneous.
## Variance Ratio test: F = 0.023/0.018 = 1.336, df = 821;1299, p-value = 0.000
## Levene's test, Brown-Forsythe: t = 3.449, df = 2120, p-value = 0.001
##
##
## ------ Infer ------
##
## --- Assume equal population variances of fnbmd for each sex
##
## t-cutoff for 95% range of variation: tcut = 1.961
## Standard Error of Mean Difference: SE = 0.006
##
## Hypothesis Test of 0 Mean Diff: t-value = 21.080, df = 2120, p-value = 0.000
##
## Margin of Error for 95% Confidence Level: 0.012
## 95% Confidence Interval for Mean Difference: 0.120 to 0.144
##
##
## --- Do not assume equal population variances of fnbmd for each sex
##
## t-cutoff: tcut = 1.961
## Standard Error of Mean Difference: SE = 0.006
##
## Hypothesis Test of 0 Mean Diff: t = 20.407, df = 1560.981, p-value = 0.000
##
## Margin of Error for 95% Confidence Level: 0.013
## 95% Confidence Interval for Mean Difference: 0.119 to 0.145
##
##
## ------ Effect Size ------
##
## --- Assume equal population variances of fnbmd for each sex
##
## Standardized Mean Difference of fnbmd, Cohen's d: 0.939
##
##
## ------ Practical Importance ------
##
## Minimum Mean Difference of practical importance: mmd
## Minimum Standardized Mean Difference of practical importance: msmd
## Neither value specified, so no analysis
##
##
## ------ Graphics Smoothing Parameter ------
##
## Density bandwidth for sex Male: 0.044
## Density bandwidth for sex Female: 0.034
# Trung bình và độ lệch chuẩn theo giới
tapply(df$fnbmd, df$sex, mean, na.rm = TRUE)
## Female Male
## 0.7775231 0.9096959
tapply(df$fnbmd, df$sex, sd, na.rm = TRUE)
## Female Male
## 0.1323548 0.1529898
boxplot(fnbmd ~ sex,
data = df,
main = "Femoral Neck BMD by Sex",
xlab = "Sex",
ylab = "Femoral neck BMD (g/cm2)",
col = c("pink", "lightblue"))
Nhóm chứng (n= 9): 105, 119, 100, 97, 96, 101, 94, 95, 98 Nhóm café (n= 9): 96, 99, 94, 89, 96, 93, 88, 105, 88 Nhập dữ liệu trên vào R.
placebo <- c(105, 119, 100, 97, 96, 101, 94, 95, 98)
coffee <- c(96, 99, 94, 89, 96, 93, 88, 105, 88)
summary(placebo)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 94.0 96.0 98.0 100.6 101.0 119.0
summary(coffee)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 88.00 89.00 94.00 94.22 96.00 105.00
# Kiểm t hai mẫu độc lập
t_test_result <- t.test(placebo, coffee,
alternative = "two.sided",
var.equal = TRUE)
t_test_result
##
## Two Sample t-test
##
## data: placebo and coffee
## t = 1.9948, df = 16, p-value = 0.06339
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -0.3972398 13.0639064
## sample estimates:
## mean of x mean of y
## 100.55556 94.22222
Phép kiểm t hai mẫu độc lập được sử dụng để so sánh chỉ số RER trung bình giữa nhóm chứng (placebo) và nhóm sử dụng café. Kết quả cho thấy giá trị trung bình RER của hai nhóm có sự khác biệt. Tuy nhiên, sự khác biệt này (có/không) đạt ý nghĩa thống kê với mức ý nghĩa 5% (p = …).
Điều này cho thấy việc sử dụng café (có/không) làm thay đổi đáng kể chỉ số RER so với nhóm chứng trong mẫu nghiên cứu.
Nếu p < 0.05 → “có ý nghĩa thống kê”
Nếu p ≥ 0.05 → “không có ý nghĩa thống kê”
library(simpleboot)
## Simple Bootstrap Routines (1.1-8)
library(boot)
set.seed(123) # Để kết quả tái lập được
boot_result <- two.boot(placebo, coffee, FUN = mean, R = 10000)
boot.ci(boot_result, type = c("perc","bca","norm", "basic"))
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 10000 bootstrap replicates
##
## CALL :
## boot.ci(boot.out = boot_result, type = c("perc", "bca", "norm",
## "basic"))
##
## Intervals :
## Level Normal Basic
## 95% ( 0.383, 12.188 ) ( 0.111, 11.778 )
##
## Level Percentile BCa
## 95% ( 0.889, 12.556 ) ( 0.778, 12.444 )
## Calculations and Intervals on Original Scale
Phương pháp bootstrap với 10.000 lần lặp được sử dụng để ước lượng khoảng tin cậy 95% của chênh lệch trung bình RER giữa nhóm placebo và nhóm caffee. Kết quả cho thấy khoảng tin cậy bootstrap chênh lệch trung bình là [0.889 ; 12.556].
Do khoảng tin cậy không chứa giá trị 0, nên có thể kết luận rằng sự khác biệt RER giữa hai nhóm có ý nghĩa thống kê. Kết quả bootstrap phù hợp với kết quả thu được từ phép kiểm t, qua đó làm tăng độ tin cậy của kết luận.
Bootstrap không yêu cầu giả định phân phối chuẩn, do đó kết quả có tính vững (robust) hơn so với phương pháp kiểm định tham số truyền thống.
set.seed(123) # Để kết quả tái lập được
# Số lần bootstrap
B <- 10000
# Chênh lệch trung bình quan sát
obs_diff <- mean(placebo) - mean(coffee)
# Bootstrap
boot_diff <- replicate(B, {
mean(sample(placebo, replace = TRUE)) -
mean(sample(coffee, replace = TRUE))
})
# Khoảng tin cậy 95% bootstrap
boot_ci <- quantile(boot_diff, probs = c(0.025, 0.975))
obs_diff
## [1] 6.333333
boot_ci
## 2.5% 97.5%
## 0.8888889 12.4444444
Đặc điểm Nam (n= xxx) Nữ (n= xxx) Giá trị P Gãy xương Ca gãy xương (%) Ca gãy xương (%)
library(table1)
table1(~ fx + as.factor(fx) | sex, data = df)
| Female (N=1317) |
Male (N=845) |
Overall (N=2162) |
|
|---|---|---|---|
| fx | |||
| Mean (SD) | 0.304 (0.460) | 0.170 (0.376) | 0.252 (0.434) |
| Median [Min, Max] | 0 [0, 1.00] | 0 [0, 1.00] | 0 [0, 1.00] |
| as.factor(fx) | |||
| 0 | 916 (69.6%) | 701 (83.0%) | 1617 (74.8%) |
| 1 | 401 (30.4%) | 144 (17.0%) | 545 (25.2%) |
chisq.test(df$fx, df$sex)
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: df$fx and df$sex
## X-squared = 48.363, df = 1, p-value = 3.542e-12
Trong tổng số 2.162 đối tượng nghiên cứu, tỉ lệ gãy xương chung là 25,2%. Ở nhóm nữ (N = 1.317), có 401 trường hợp gãy xương, chiếm 30,4%, trong khi ở nhóm nam (N = 845), có 144 trường hợp gãy xương, tương ứng 17,0%. Như vậy, tỉ lệ gãy xương ở nữ cao hơn rõ rệt so với nam.
Giá trị trung bình của biến gãy xương (fx) ở nữ là 0,304 (SD = 0,460), cao hơn so với nam là 0,170 (SD = 0,376). Điều này cho thấy nguy cơ gãy xương trung bình ở nữ cao hơn so với nam trong quần thể nghiên cứu.
📌 (Vì fx là biến nhị phân 0/1 nên mean chính là tỉ lệ)
Kết quả cho thấy nữ giới có tỉ lệ gãy xương cao hơn đáng kể so với nam giới trong thời gian theo dõi. Điều này gợi ý rằng giới tính có thể là một yếu tố liên quan đến nguy cơ gãy xương.
# Bảng chéo --> phuong an cua Chat GPT
tab_fx_sex <- table(df$sex, df$fx)
tab_fx_sex
##
## 0 1
## Female 916 401
## Male 701 144
# Tỉ lệ theo hàng (%)
prop.table(tab_fx_sex, margin = 1) * 100
##
## 0 1
## Female 69.55201 30.44799
## Male 82.95858 17.04142
chisq_test <- chisq.test(tab_fx_sex)
chisq_test
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: tab_fx_sex
## X-squared = 48.363, df = 1, p-value = 3.542e-12