2016-05-04 3 views
0

Rでは、同じ値の列(同じ文字でグループ化されたもの)の合計から値の列(列 't1'の文字でグループ化されたもの)の合計を差し引きたい列「t2」)。すべての手紙と毎年のグループについてこのプロセスを繰り返します。複数のグループごとにデータフレーム列の差異を見つける

set.seed(3)  
df <- data.frame(age = rep(1:3,each=25), 
         t1 = rep(expand.grid(LETTERS[1:5],LETTERS[1:5])[,1],3), 
         t2 = rep(expand.grid(LETTERS[1:5],LETTERS[1:5])[,2],3), 
        value = sample(1:10,75,replace=T)) 

このデータフレームは、「年齢」列に3つの値、カテゴリ(t1およびt2)および関連する値(値)を持つ2つの列を示します。一例として、

は、ここでは「A」のために働くかもしれない方法である:

library(plyr); 

# extract rows with A 
df2 <- df[df$t1=="A" | df$t2=="A",] 
# remove where t1 and t2 are the same (not needed) 
df2 <- df2[df2$t1 != df2$t2,] 
# use ddply to subtract sum of 'value' for A in t1 from t2 
df2 <- ddply(df2, .(age), transform, change = sum(value[t2=="A"])-sum(value[t1=="A"])) 
# create a name 
df2$cat <- "A" 
# remove all the duplicate rows, just need one summary value 
df2 <- df2[ !duplicated(df2$change), ] 
# keep summary data 
df2 <- df2[,c(1,6,5)] 

は今、私はこのケースではT1とT2で発生するすべての値(A、Bのためにこれを行う必要があり、 C & D)、12行の要約を作成します。

私はループを試しました。

for (c in as.character(unique(df$t1))) 

しかしnowehere

おかげ

+0

私は何かが不足していると思います...どうすればt1またはt2から値を減算できますか?これらの列は文字です。 –

+0

説明がわかりません。 (ある意味では、 "A"は通常の意味ではデータの変数ではありません)。期待される結果を含むdf_outを提供するだけかもしれません。 – Frank

+1

申し訳ありませんが、それは私の貧しい説明かもしれません。ここで、t2 = Aであり、次に、「値」を合計し、t1 = Aであれば合計「値」である。前者から後者を引く。毎年のグループごとにユニークな手紙ごとに繰り返す。 – Sam

答えて

2

を集約とマージを含む1つのベースRソリューションです:

# aggregate by age and t1 or t2 
t1Agg <- aggregate(value ~ t1 + age, data=df, FUN=sum) 
t2Agg <- aggregate(value ~ t2 + age, data=df, FUN=sum) 

# merge aggregated data 
aggData <- merge(t1Agg, t2Agg, by.x=c("age","t1"), by.y=c("age","t2")) 
names(aggData) <- c("age", "t", "value.t1", "value.t2") 

aggData$diff <- aggData$value.t1 - aggData$value.t2 
+0

ありがとう、素敵で簡単、現実には集約したほんの簡単なステップですが、私はddplyでうんざりしてしまいました。 – Sam

1

は、私が最初にあなたのデータを片付け推薦する多くを持って、あなたがspreadsummariseと新しい列を追加することができます:ここで

# Make reproducible 
set.seed(4) 
df <- data.frame(age = rep(1:3,each=25), 
       t1 = rep(expand.grid(LETTERS[1:5],LETTERS[1:5])[,1],3), 
       t2 = rep(expand.grid(LETTERS[1:5],LETTERS[1:5])[,2],3), 
       value = sample(1:10,75,replace=T)) 

library(tidyr) 
library(dplyr) 

df_tidy <- gather(df, t_var, t_val, -age, -value) 
sample_n(df_tidy, 3) 
#  age value t_var t_val 
# 104 2  6 t2  A 
# 48 2  9 t1  C 
# 66 3  7 t1  A 

df_tidy %>% 
    group_by(age, t_var, t_val) %>% 
    summarise(val_sum = sum(value)) %>% 
    spread(t_var, val_sum) %>% 
    mutate(diff = t1 - t2) 

#  age t_val t1 t2 diff 
# (int) (chr) (int) (int) (int) 
# 1  1  A 30 22  8 
# 2  1  B 32 32  0 
# 3  1  C 27 28 -1 
# 4  1  D 38 39 -1 
# 5  1  E 30 36 -6 
# 6  2  A 36 35  1 
# 7  2  B 26 30 -4 
# 8  2  C 40 27 13 
# 9  2  D 27 31 -4 
# 10  2  E 28 34 -6 
# 11  3  A 26 39 -13 
# 12  3  B 19 26 -7 
# 13  3  C 31 29  2 
# 14  3  D 41 33  8 
# 15  3  E 39 29 10 
関連する問題