データフレームの3列ごとに平均を計算する方法は?

データフレームの3列ごとに平均を計算する方法は?

次のデータフレームがあります。

> head(dat_sg2)
               DwoC_2318_norm.1 DwoC_2318_norm.2 DwoC_2318_norm.3 DwoC_3395_norm.1 DwoC_3395_norm.2 DwoC_3395_norm.3 DwoC_6154_norm.1
Ku8QhfS0n_hIOABXuE         4.865523         4.806292         4.478393         4.539028         4.050325         4.440587         4.110421
Bx496XsFXiAlj.Eaeo         6.123590         6.423548         6.561369         5.856075         5.858094         5.930103         5.801459
W38p0ogk.wIBVRXllY         7.791964         7.648746         7.705958         7.561884         7.699504         7.676182         7.479021
QIBkqIS9LR5DfTlTS8         5.810877         5.579234         5.698071         5.088198         5.076525         5.367539         3.887972
BZKiEvS0eQ305U0v34         6.294961         6.358164         5.876450         5.414746         5.664350         5.924501         4.446681
6TheVd.HiE1UF3lX6g         5.268226         5.337910         5.420836         5.604646         5.007336         5.101670         5.590275

3列ごとの平均を含むデータフレームを取得する必要があります。したがって、私が望む結果は6行と2列です(例:DwoC_2318とDwoC_3395)。

出力は次のとおりです。

                    DwoC_2318_mean       DwoC_3395_mean
Ku8QhfS0n_hIOABXuE       4.716736           4.343313
Bx496XsFXiAlj.Eaeo       …                     …
W38p0ogk.wIBVRXllY       …                     …
QIBkqIS9LR5DfTlTS8       …                     …
BZKiEvS0eQ305U0v34       …                     …
6TheVd.HiE1UF3lX6g       …                     …

どこ:

4.716736=(4.865523+4.806292+4.478393)/3

私の元のデータフレームは21列と約20,000行で構成されています。

ここでは、rowMeansでR適用関数を使用できるようですが、これを適用して3列ごとに平均を計算する方法がわかりません。

私は15568行と21列を持つデータフレーム全体(df)でこれを行いたいと思います。

groups=c(1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7)
x=apply(df,1,function(x) tapply(x, list(groups), mean))

ただし、15568行と7列は出力されません。

7行、15568列。

答え1

3行ごとに平均を計算する方が簡単なので、まずデータフレームを転置してこの問題を解決しました。後で私はそれを再び回した。

#read in data
df=read.table("DwoC", header=T)
#transpose it
df <- as.data.frame(t(df))
# remove .1,.2,...strings from row names, and save unique row names
rn=unique(gsub("\\..*","",rownames(df)))
n=3
# calculate means between each 3 rows
dd=aggregate(df,list(rep(1:(nrow(df)%/%n+1),each=n,len=nrow(df))),mean)[-1]
# transpose it back
dt <- as.data.frame(t(dd))
# rename columns as the names were lost during transpose step
names(dt)=rn 

答え2

に基づいて列サブセットの行平均の計算

> df = read.table('file')
> 
> data.frame(ID=df[,0], DwoC_2318_mean=rowMeans(df[1:3]), DwoC_3395_mean=rowMeans(df[4:6]))
                   DwoC_2318_mean DwoC_3395_mean
Ku8QhfS0n_hIOABXuE       4.716736       4.343313
Bx496XsFXiAlj.Eaeo       6.369502       5.881424
W38p0ogk.wIBVRXllY       7.715556       7.645857
QIBkqIS9LR5DfTlTS8       5.696061       5.177421
BZKiEvS0eQ305U0v34       6.176525       5.667866
6TheVd.HiE1UF3lX6g       5.342324       5.237884
> 

答え3

私はRに精通していないので、awk解決策を試してみましょう。

$ awk 'NR == 1 { next } { j=0; for (i = 2; i+2 <= NF; i+=3) m[++j] = ($(i+0)+$(i+1)+$(i+2))/3; $0 = $1; for (i=1; i<=j; ++i) $(i+1)=m[i]; print }' file
Ku8QhfS0n_hIOABXuE 4.71674 4.34331
Bx496XsFXiAlj.Eaeo 6.3695 5.88142
W38p0ogk.wIBVRXllY 7.71556 7.64586
QIBkqIS9LR5DfTlTS8 5.69606 5.17742
BZKiEvS0eQ305U0v34 6.17653 5.66787
6TheVd.HiE1UF3lX6g 5.34232 5.23788

注釈付きawkスクリプト:

# Skip header
NR == 1 { next }

{
    j = 0

    # Go through the columns from column 2 onwards in groups of thee columns,
    # calculating the average of the group and store it in the array m.
    for (i = 2; i + 2 <= NF; i += 3)
        m[++j] = ($(i+0) + $(i+1) + $(i+2))/3

    # Rewrite the current row as the first column only.
    $0 = $1

    # Add the calculated averages as new columns after column 1.
    for (i = 1; i <= j; ++i)
        $(i+1) = m[i]

    print
}

コードでは、列1の後の列数が3の倍数であると仮定します。例のように、末尾の列が 1 つまたは 2 つある場合、データは削除されます。

関連情報