2

治療、用量、結果(プラスまたはマイナス)の3つの変数を含むデータフレームがあります。治療と投与量ごとに複数の観察結果があります。データを折りたたんで、治療と線量の関数としての各結果の数、および観測数を示す分割表を出力しようとしています。例えば:

treatment dose outcome    
control 0 0
control 0 0
control 0 0
control 0 1
treatmentA 1 0
treatmentA 1 1
treatmentA 1 1
treatmentA 2 1
treatmentA 2 1 
treatmentA 2 1

必要な出力は次のとおりです。

treatment dose outcome n
control 0 0 1 4
treatmentA 1 2 3
treatmentA 2 3 3

私はこれを一日中遊んでいましたが、各観測の各結果の頻度を取得できること以上の幸運はありませんでした。私が見落としていた提案(Rマニュアルや例のどの部分を指摘することを含む)をいただければ幸いです。

ありがとう!

R

4

5 に答える 5

5

素晴らしいパッケージを使用したソリューションは次のdata.tableとおりです。

library(data.table)
x <- data.table(read.table( text = "treatment dose outcome    
control 0 0
control 0 0
control 0 0
control 0 1
treatmentA 1 0
treatmentA 1 1
treatmentA 1 1
treatmentA 2 1
treatmentA 2 1 
treatmentA 2 1", header = TRUE)
x[, list(outcome = sum(outcome), count = .N), by = 'treatment,dose']

生産する

    treatment dose outcome count
1:    control    0       1     4
2: treatmentA    1       2     3
3: treatmentA    2       3     3
于 2013-01-29T01:38:34.433 に答える
4

他の回答で提案されているように追加のライブラリを使用したくない場合は、次を試すことができます。

> df
    treatment dose outcome
1     control    0       0
2     control    0       0
3     control    0       0
4     control    0       1
5  treatmentA    1       0
6  treatmentA    1       1
7  treatmentA    1       1
8  treatmentA    2       1
9  treatmentA    2       1
10 treatmentA    2       1

> dput(df)
structure(list(treatment = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L), .Label = c("control", "treatmentA"), class = "factor"), 
    dose = c(0L, 0L, 0L, 0L, 1L, 1L, 1L, 2L, 2L, 2L), outcome = c(0L, 
    0L, 0L, 1L, 0L, 1L, 1L, 1L, 1L, 1L)), .Names = c("treatment", 
"dose", "outcome"), class = "data.frame", row.names = c(NA, -10L
))

次に、関数を使用して列aggregateのカウントと合計を取得しますoutcome

> nObs <- aggregate(outcome ~ treatment + dose, data = df, length)
> sObs <- aggregate(outcome ~ treatment + dose, data = df, sum)

集計列の名前を適切に変更する

names(nObs) <- c('治療', '投与', 'カウント')

> names(sObs) <- c('treatment', 'dose', 'sum')

> nObs
   treatment dose count
1    control    0     4
2 treatmentA    1     3
3 treatmentA    2     3


> sObs
   treatment dose sum
1    control    0   1
2 treatmentA    1   2
3 treatmentA    2   3

この場合、merge同じ名前のすべての列で上記の 2 つを結合するために使用します。treatmentdose

> result <- merge(nObs, sObs)
> result
   treatment dose count sum
1    control    0     4   1
2 treatmentA    1     3   2
3 treatmentA    2     3   3
于 2013-01-29T01:36:37.680 に答える
3

私が正しく理解していれば、これはdata.tableライブラリで簡単です。まず、ライブラリをロードしてデータを読み込みます:

library(data.table)

data <- read.table(header=TRUE, text="
treatment dose outcome    
control 0 0
control 0 0
control 0 0
control 0 1
treatmentA 1 0
treatmentA 1 1
treatmentA 1 1
treatmentA 2 1
treatmentA 2 1 
treatmentA 2 1")

次に、 および 列をテーブル キー (インデックス) として を作成data.tabletreatmentますdose

data <- data.table(data, key="treatment,dose")

次に、構文を使用して集計しdata.tableます。

data[, list(outcome=sum(outcome), n=length(outcome)), by=list(treatment,dose)]

    treatment dose outcome n
1:    control    0       1 4
2: treatmentA    1       2 3
3: treatmentA    2       3 3
于 2013-01-29T01:36:28.800 に答える
2

私見、SQLは過小評価されています。:)

# read in your example data as `x`
x <- read.table( text = "treatment dose outcome    
control 0 0
control 0 0
control 0 0
control 0 1
treatmentA 1 0
treatmentA 1 1
treatmentA 1 1
treatmentA 2 1
treatmentA 2 1 
treatmentA 2 1",h=T)

# load the sql data frame library
library(sqldf)

# create a new table of all unique `treatment` and `dose` columns,
# summing the `outcome` column and 
# counting the number of records in each combo
y <- sqldf( 'SELECT treatment, dose , 
                    sum( outcome ) as outcome , 
                    count(*) as n 
             FROM   x 
             GROUP BY treatment, dose' )

# check the results
y
于 2013-01-29T01:19:16.307 に答える
2

別の 2 つのオプションを次に示します (data.table構文の簡潔さではこのアプローチが明らかに優れているとはいえ)。

最初はave内で使用しますwithinave1 つ以上の変数でグループ化された変数 (最初に言及された変数) に関数を適用できます。unique不要になった「結果」列を削除した後、出力をラップします。

unique(within(df, {
  SUM <- ave(outcome, treatment, dose, FUN = sum)
  COUNT <- ave(outcome, treatment, dose, FUN = length)
  rm(outcome)
}))
#    treatment dose COUNT SUM
# 1    control    0     4   1
# 5 treatmentA    1     3   2
# 8 treatmentA    2     3   3

ベース R の 2 番目のソリューションは、@geektrader の回答と非常によく似ていますが、集約への 1 回の呼び出しでsumとの両方を計算します。lengthただし、「欠点」があります。その結果は、実際にはマトリックスでcbindある「列」になります。私が何を意味するかを見るdata.frameために結果を見てください。str

temp <- aggregate(outcome ~ treatment + dose, df, 
                  function(x) cbind(sum(x), length(x)))
str(temp)
# 'data.frame':  3 obs. of  3 variables:
#  $ treatment: Factor w/ 2 levels "control","treatmentA": 1 2 2
#  $ dose     : int  0 1 2
#  $ outcome  : int [1:3, 1:2] 1 2 3 4 3 3

colnames(temp$outcome) <- c("SUM", "COUNT")
temp
#    treatment dose outcome.SUM outcome.COUNT
# 1    control    0           1             4
# 2 treatmentA    1           2             3
# 3 treatmentA    2           3             3

慣れ親しんだ方法でデータにアクセスしようとすると、期待した結果が得られない可能性があるため、ストレージ構造を「欠点」として言及します。

temp$outcome.SUM
# NULL

temp$outcome
#      SUM COUNT
# [1,]   1     4
# [2,]   2     3
# [3,]   3     3

代わりに、次の方法でアクセスする必要があります。

temp$outcome[, "SUM"] ## or temp$outcome[, 1]
# [1] 1 2 3
于 2013-01-29T04:35:22.727 に答える