2016-12-30 7 views
0

私は小さな問題があります。私はデータフレームに取り組んでいます。私は10分、「期間」の各イベントについて、「強度」の累積合計を計算したいRの別の列の条件に基づいて列の特定のセルを集計する方法

df1 
Duration Intensity 
NA    NA 
10   0.1016 
10   0.0254 
NA    NA 
NA    NA 
10   0.0508 
10   0.0508 
10   0.1016 
NA    NA 
10   0.0254 

次のようにそれはあります。言い換えれば、 "Intensity"カラムの "NA"値の間に "Intensity"の値を合計したいと思います。出力は次のようになります。

DF2

Duration Intensity Intensity_sum 
NA    NA 
10   0.1016 
10   0.0254  0.127 
NA    NA 
NA    NA 
10   0.0508 
10   0.0508 
10   0.1016  0.2032 
NA    NA 
10   0.0254  0.0254 

私は、次のコードを試してみました:

library(dplyr)  
df2 <- as.data.frame(mutate(df1,Intensity_sum = with(df1,Duration==10,cumsum(Intensity)))) 

をしかし、私は唯一のTRUEまたはFALSEの結果ではなく、値を受け付けております。

+3

の可能性のある重複した[グループによって変数を合計する方法は?](http://stackoverflow.com/questions/1660124/how-to-sum-a-variable-by-group) – nrussell

+0

は親切@nrussell OPはグループIDを最初に構築し、集約された合計を各グループの最終的な観測に「マージ」する必要があることを除いては、 – lmo

+0

@nrussellありがとう、しかし私の問題はまったく同じものではありません – happy123

答えて

2

data.tableを使用できます。論理ベクトル(!is.na(Duration))のランレングスIDでグループ分けされた 'data.frame'を 'data.table'(setDT(df1))に変換すると、 'Intensity'のsumが 'Intensity_sum and later replace the duplicated`要素として割り当てられます(:=) (上記のように)rleidによって「NA」

library(data.table) 
setDT(df1)[, Intensity_sum := sum(Intensity), rleid(!is.na(Duration))] 
df1[duplicated(Intensity_sum, fromLast=TRUE), Intensity_sum := NA] 
df1 
#  Duration Intensity Intensity_sum 
# 1:  NA  NA   NA 
# 2:  10 0.1016   NA 
# 3:  10 0.0254  0.1270 
# 4:  NA  NA   NA 
# 5:  NA  NA   NA 
# 6:  10 0.0508   NA 
# 7:  10 0.0508   NA 
# 8:  10 0.1016  0.2032 
# 9:  NA  NA   NA 
#10:  10 0.0254  0.0254 

あるいは我々ができる単一行のグループとし、「強」のsum

setDT(df1)[, Intensity_sum := rep(c(NA,sum(Intensity)), c(.N-1, 1)), rleid(!is.na(Duration))] 
と共に NAを複製して新しい列を割り当てます
0

Iは以下を示唆している第四のdata.table方法を使用して、それがベースR.で所望の結果を達成することが可能である。この方法は、ここavereplace

ave(df$Intensity, cumsum(is.na(df$Intensity)), 
    FUN=function(x) replace(NA, (seq_along(x) == length(x) & length(x) > 1), 
          sum(x, na.rm=TRUE))) 
[1]  NA  NA 0.1270  NA  NA  NA  NA 0.2032  NA 0.0254 

を使用していくつかの追加data.tableオプションが

df[, val := ifelse(is.na(shift(Intensity, type="lead")), 
    sum(Intensity, na.rm=TRUE), NA), by=cumsum(is.na(Intensity))] 
あります

この場合、グループ化はcumsum関数を使用して実行され、合計の配置はは、shiftを使用して、NA境界をチェックします。

隣接する数値に1つのNA値がある場合、これは少し遅く、NAの代わりに0が追加されます。 ifelseの最初の引数は、これが起こらないように変更できます。

第2に、cを使用し、ifelseの代わりにサブセットを使用するより高速なソリューションです。 NAの単一の行がNAの好きな操作を活用するために、わずかにこの方法を見直し0

df[, val2 := c(NA, sum(Intensity, na.rm=TRUE))[(seq_len(.N) == .N &.N > 1) + 1], 
    by=cumsum(is.na(Intensity))] 

のではなく、受信およびNAとなるように、私はロジックを追加しました。我々は以下を得る。

この方法は、NA^xここでx!= 0はNAを返しますが、NA^0は1を返し、NA^FALSENA^0に相当します。

第4の代替案は、replaceを使用することです。この関数は、指定されたインデックスの値でベクトルを置き換えます。

df[, val4 := replace(NA, (seq_len(.N) == .N & .N != 1), 
        sum(Intensity, na.rm=TRUE)), 
    by=cumsum(is.na(Intensity))] 

以下の3つの方法の結果を示します。

df 
    Duration Intensity val3 val val2 val4 
1:  NA  NA  NA  NA  NA  NA 
2:  10 0.1016  NA  NA  NA  NA 
3:  10 0.0254 0.1270 0.1270 0.1270 0.1270 
4:  NA  NA  NA 0.0000  NA  NA 
5:  NA  NA  NA  NA  NA  NA 
6:  10 0.0508  NA  NA  NA  NA 
7:  10 0.0508  NA  NA  NA  NA 
8:  10 0.1016 0.2032 0.2032 0.2032 0.2032 
9:  NA  NA  NA  NA  NA  NA 
10:  10 0.0254 0.0254 0.0254 0.0254 0.0254 
関連する問題