# ←この記号の後は次の改行までコメントになります。
# データフレームにアクセスして記述統計量を求める(連続変数)。
# まずはデータ空間をクリアしておいてから、
rm(list=ls())
# 乱数的に作成した架空のデータセットを使います。
# ここから44行目まではサンプルデータセットの作成です。
set.seed(1111)
Dataset.0<-
data.frame(
Sex=factor(rnorm(n=800,mean=0.5,sd=1)>0,labels=c("Male","Female")),
Age=50+rpois(n=800,lambda=25)+round(rnorm(n=800,mean=0,sd=5),0),
Severity=rpois(n=800,lambda=3))
Dataset.0$Comorbidity=
rpois(n=800,lambda=1)+round(Dataset.0$Age*rnorm(n=800,mean=0.03,sd=0.08)^2,0)
Dataset.0$UnknownConfounder=
factor(
with(Dataset.0,
rnorm(n=800,mean=0)+
I(Sex=="Male")*rnorm(n=800,mean=0.02)*0.01+
I(Age-80)*rnorm(n=800,mean=0.002)*0.001+
I(Severity>3)*rnorm(n=800,mean=0.05)*0.01)>1,
labels=c("No","Yes"))
Dataset.0$Intervention<-
factor(
with(Dataset.0,
rnorm(n=800,mean=0)+
I(Sex=="Female")*rnorm(n=800,mean=0.2)+
I(Age-80)*rnorm(n=800,mean=-0.1)*0.1+
I(Severity-2)*rnorm(n=800,mean=0.4)+
I(Comorbidity-1)*rnorm(n=800,mean=-1.2)*0.6+
I(UnknownConfounder=="Yes")*rnorm(n=800,mean=0.2)*0.2)>0,
labels=c("No","Yes"))
Dataset.0$Outcome<-
factor(
with(Dataset.0,
rnorm(n=800,mean=0)*10+
I(Sex=="Male")*rnorm(n=800,mean=0.01)+
I(Age-75)*rnorm(n=800,mean=0.3)*5+
I(Severity-1)*rnorm(n=800,mean=0.7)*6+
I(Comorbidity-1)*rnorm(n=800,mean=0.9)*5+
I(Intervention=="Yes")*rnorm(n=800,mean=-0.6)*4+
I(UnknownConfounder=="Yes")*rnorm(n=800,mean=0.3)*0.7)>20,labels=c("No","Yes"))
Dataset.0$UnknownConfounder<-NULL
# Dataset.0というデータフレームが出来上がっているはずです。
# RStudioを使っている方は、右上のウィンドウのEnvironmentタグに表示されています。
# いつものごとく、中身を見てみましょう。
nrow(Dataset.0) #サンプル数
## [1] 800
head(Dataset.0,20) #先頭から20行を見ます。
## Sex Age Severity Comorbidity Intervention Outcome
## 1 Female 77 0 1 Yes No
## 2 Female 64 0 3 Yes Yes
## 3 Female 84 3 0 Yes Yes
## 4 Female 67 3 0 No No
## 5 Female 70 2 4 No No
## 6 Male 87 3 0 Yes No
## 7 Female 82 4 0 Yes No
## 8 Female 79 5 1 No Yes
## 9 Female 64 5 0 No Yes
## 10 Female 80 6 3 Yes Yes
## 11 Male 61 1 3 No No
## 12 Female 76 4 4 Yes No
## 13 Male 72 3 2 No No
## 14 Male 83 3 1 Yes No
## 15 Female 77 2 0 No No
## 16 Female 77 0 3 No No
## 17 Female 78 2 0 Yes No
## 18 Male 86 0 2 No Yes
## 19 Female 77 3 2 Yes Yes
## 20 Female 76 3 0 Yes No
summary(Dataset.0) #データセット全体の要約
## Sex Age Severity Comorbidity Intervention
## Male :254 Min. : 53.00 Min. :0.000 Min. :0.00 No :371
## Female:546 1st Qu.: 70.00 1st Qu.:2.000 1st Qu.:1.00 Yes:429
## Median : 75.00 Median :3.000 Median :1.00
## Mean : 75.02 Mean :3.027 Mean :1.48
## 3rd Qu.: 80.00 3rd Qu.:4.000 3rd Qu.:2.00
## Max. :107.00 Max. :9.000 Max. :8.00
## Outcome
## No :511
## Yes:289
##
##
##
##
# すでにsummary関数でおよその推測統計量は出ていますね。
# 連続変数
# 論文に連続変数の記述統計量を書く場合(例えばTable 1.)
# 平均と標準偏差で表すか、中央値と四分位範囲(25 percentile - 75 percentile)で
# 表されるか、ほとんどの場合はこのどちらかです。
# 年齢(Age)を用いて、どちらもやってみましょう。
mean(Dataset.0$Age) # 平均
## [1] 75.02375
sd(Dataset.0$Age) #標準偏差
## [1] 7.14717
# round関数を使って、小数点以下1桁(digits=1)と有効数字を指定します。
round(c(mean(Dataset.0$Age),sd(Dataset.0$Age)),digits=1)
## [1] 75.0 7.1
# さらに文字列に変えることもできます。この時も小数点以下1桁まで表示桁数を
# 指定する(nsmall=1)ことが必要です。
format(round(c(mean(Dataset.0$Age),sd(Dataset.0$Age)),digits=1),nsmall=1)
## [1] "75.0" " 7.1"
# よく論文にあるような表記にしてみましょう。
# 前回もでてきたpaste関数を使って、文字列を貼り合わせます。
paste(
format(round(mean(Dataset.0$Age),digits=1),nsmall=1), # 平均値、小数点以下1桁
" +/- ", # " +/- "を間に挟む
format(round(sd(Dataset.0$Age),digits=1),nsmall=1), # 標準偏差、小数点以下1桁
sep="") # 区切り記号はなし
## [1] "75.0 +/- 7.1"
# Interventionで群分けしてやってみましょう。
# 群わけのやりかたには、いくつか方法があります。
# subsetを使う
mean(subset(Dataset.0,Intervention=="Yes")$Age) # subsetの中ではDataset.0$Intervention==という表記
## [1] 75.07226
sd(subset(Dataset.0,Intervention=="Yes")$Age) # をただIntervention==と省略できます(Tips)。
## [1] 7.006799
mean(subset(Dataset.0,Intervention=="No")$Age)
## [1] 74.96765
sd(subset(Dataset.0,Intervention=="No")$Age)
## [1] 7.315221
# [...]bracketを使う
mean(Dataset.0[Dataset.0$Intervention=="Yes",]$Age)
## [1] 75.07226
sd(Dataset.0[Dataset.0$Intervention=="Yes",]$Age)
## [1] 7.006799
mean(Dataset.0[Dataset.0$Intervention=="No",]$Age)
## [1] 74.96765
sd(Dataset.0[Dataset.0$Intervention=="No",]$Age)
## [1] 7.315221
# by関数をつかう。データセット(ベクター)、群分けの条件式、関数を
# 引数に指定します。ちょっととっつきにくいですが、慣れるとスマートです。
by(Dataset.0$Age,Dataset.0$Intervention=="Yes",mean)
## Dataset.0$Intervention == "Yes": FALSE
## [1] 74.96765
## --------------------------------------------------------
## Dataset.0$Intervention == "Yes": TRUE
## [1] 75.07226
by(Dataset.0$Age,Dataset.0$Intervention=="Yes",sd)
## Dataset.0$Intervention == "Yes": FALSE
## [1] 7.315221
## --------------------------------------------------------
## Dataset.0$Intervention == "Yes": TRUE
## [1] 7.006799
# 中央値 [四分位範囲]の記載もやってみましょう。
quantile(Dataset.0$Age)
## 0% 25% 50% 75% 100%
## 53 70 75 80 107
quantile(Dataset.0$Age)[c("50%","25%","75%")] # 要素に付けられた名前を元に取り出します。
## 50% 25% 75%
## 75 70 80
quantile(Dataset.0$Age)[c(3,2,4)] # 3番目、2番め、4番目という指定でもOK。
## 50% 25% 75%
## 75 70 80
# これも論文用の表記にしてみましょう。
Qtile<-quantile(Dataset.0$Age)
paste(
format(round(Qtile[3],digits=0),nsmall=0), # 中央値、小数点以下0桁
" [", # [
format(round(Qtile[2],digits=0),nsmall=0), # 25パーセンタイル、小数点以下0桁
", ", # ,
format(round(Qtile[4],digits=0),nsmall=0), # 75パーセンタイル、小数点以下0桁
"]", # ]
sep="") # 区切り記号はなし
## [1] "75 [70, 80]"
# 群分けは同様です。
# subsetを使う
quantile(subset(Dataset.0,Intervention=="Yes")$Age)
## 0% 25% 50% 75% 100%
## 53 70 75 80 96
quantile(subset(Dataset.0,Intervention=="No")$Age)
## 0% 25% 50% 75% 100%
## 57 70 75 80 107
# bracketを使う
quantile(Dataset.0[Dataset.0$Intervention=="Yes",]$Age)
## 0% 25% 50% 75% 100%
## 53 70 75 80 96
quantile(Dataset.0[Dataset.0$Intervention=="No",]$Age)
## 0% 25% 50% 75% 100%
## 57 70 75 80 107
# byを使う
by(Dataset.0$Age,Dataset.0$Intervention=="Yes",quantile)
## Dataset.0$Intervention == "Yes": FALSE
## 0% 25% 50% 75% 100%
## 57 70 75 80 107
## --------------------------------------------------------
## Dataset.0$Intervention == "Yes": TRUE
## 0% 25% 50% 75% 100%
## 53 70 75 80 96
# 検定は2つに分割したベクターをt.test関数に投入します。
t.test(subset(Dataset.0,Intervention=="Yes")$Age,subset(Dataset.0,Intervention=="No")$Age)
##
## Welch Two Sample t-test
##
## data: subset(Dataset.0, Intervention == "Yes")$Age and subset(Dataset.0, Intervention == "No")$Age
## t = 0.20567, df = 770.65, p-value = 0.8371
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -0.8938104 1.1030226
## sample estimates:
## mean of x mean of y
## 75.07226 74.96765
t.test(Dataset.0[Dataset.0$Intervention=="Yes",]$Age,Dataset.0[Dataset.0$Intervention=="No",]$Age)
##
## Welch Two Sample t-test
##
## data: Dataset.0[Dataset.0$Intervention == "Yes", ]$Age and Dataset.0[Dataset.0$Intervention == "No", ]$Age
## t = 0.20567, df = 770.65, p-value = 0.8371
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -0.8938104 1.1030226
## sample estimates:
## mean of x mean of y
## 75.07226 74.96765
t.test(Dataset.0$Age~Dataset.0$Intervention) #こういう表記は便利ですね。
##
## Welch Two Sample t-test
##
## data: Dataset.0$Age by Dataset.0$Intervention
## t = -0.20567, df = 770.65, p-value = 0.8371
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -1.1030226 0.8938104
## sample estimates:
## mean in group No mean in group Yes
## 74.96765 75.07226
# U-testはwilcox.test関数をつかいます。
wilcox.test(subset(Dataset.0,Intervention=="Yes")$Age,subset(Dataset.0,Intervention=="No")$Age)
##
## Wilcoxon rank sum test with continuity correction
##
## data: subset(Dataset.0, Intervention == "Yes")$Age and subset(Dataset.0, Intervention == "No")$Age
## W = 80301, p-value = 0.8248
## alternative hypothesis: true location shift is not equal to 0
wilcox.test(Dataset.0[Dataset.0$Intervention=="Yes",]$Age,Dataset.0[Dataset.0$Intervention=="No",]$Age)
##
## Wilcoxon rank sum test with continuity correction
##
## data: Dataset.0[Dataset.0$Intervention == "Yes", ]$Age and Dataset.0[Dataset.0$Intervention == "No", ]$Age
## W = 80301, p-value = 0.8248
## alternative hypothesis: true location shift is not equal to 0
wilcox.test(Dataset.0$Age~Dataset.0$Intervention) #こういう表記は便利ですね。
##
## Wilcoxon rank sum test with continuity correction
##
## data: Dataset.0$Age by Dataset.0$Intervention
## W = 78858, p-value = 0.8248
## alternative hypothesis: true location shift is not equal to 0
# 前回作ったTableに平均値をくっつけてみましょう
Table1<-c("Variables","Control","Active","P-value") # Table1の1行目を作ります。
tab<-xtabs(~Sex+Intervention,data=Dataset.0) # 2行目(Sex)のクロス集計表の作成
row.2<- # 2行目の文字列を作る(前回参照)。
c("Female sex",
paste(tab[2,1]," (",round(tab[2,1]/sum(tab[,1])*100,0),")",sep=""),
paste(tab[2,2]," (",round(tab[2,2]/sum(tab[,2])*100,0),")",sep=""),
format(round(chisq.test(tab)$p.value,3),nsmall=3))
tab<- # 2行目(Sex)のクロス集計表の作成
matrix(
c(mean(Dataset.0[Dataset.0$Intervention=="Yes",]$Age), # 必要な平均値と標準偏差を配列に並べます。
mean(Dataset.0[Dataset.0$Intervention=="No",]$Age), # もう少しスマートな方法もあるのですが、、、
sd(Dataset.0[Dataset.0$Intervention=="Yes",]$Age), # いずれ解説します
sd(Dataset.0[Dataset.0$Intervention=="No",]$Age)),
ncol=2)
row.3<- # 2行目(Sex)のクロス集計表の作成
c("Age, year old", # 今回はさらに難しいですね
paste(format(round(tab[1,1],1),nsmall=1)," +/- ",format(round(tab[1,2],1),nsmall=1),sep=""),
paste(format(round(tab[2,1],1),nsmall=1)," +/- ",format(round(tab[2,2],1),nsmall=1),sep=""),
format(round(
t.test(Dataset.0[Dataset.0$Intervention=="Yes",]$Age,
Dataset.0[Dataset.0$Intervention=="No",]$Age)$p.value,3),nsmall=3))
Table1<-
rbind(
Table1,
row.2,
row.3
)
rownames(Table1)<-NULL
Table1
## [,1] [,2] [,3] [,4]
## [1,] "Variables" "Control" "Active" "P-value"
## [2,] "Female sex" "256 (69)" "290 (68)" "0.727"
## [3,] "Age, year old" "75.1 +/- 7.0" "75.0 +/- 7.3" "0.837"
# 演習
# Table1を、性別を"Male sex"に年齢を中央値と四分位での表記にそれぞれ変更して
# 作ってみてください。