2016-10-24 8 views
4

に基づいて行の値を引く:R:次のように私は、データセットを持っている別の列

Group Type Income 
A  X  1000 
A  Y  500 
B  Y  2000 
B  X  1500 
C  X  700 
D  Y  600 

次のように私は出力を必要とする:私は考えることができる

Group Diff 
    A  500 
    B  -500 
    C  700 
    D  -600 

一つのアプローチは、分離していますタイプXとタイプYのデータを入力し、XまたはYが存在しないグループの所得を0として追加し、各グループのようなデータをマージするには、IncomeXという名前の列とIncomeYという名前の列があります。

これを行う簡単な方法はありますか?

答えて

4

私はこのようにそれを行うだろう:(dplyrreshape2パッケージを使用して)

library("dplyr") 
library("reshape2") 

t <- read.table(text = "Group Type Income 
A  X  1000 
       A  Y  500 
       B  Y  2000 
       B  X  1500 
       C  X  700 
       D  Y  600", header = TRUE) 

t %>% 
    dcast(Group ~ Type, value.var = "Income", fill = 0) %>% 
    mutate(Diff = X - Y) %>% 
    select(Group, Diff) 

# Group Diff 
# 1  A 500 
# 2  B -500 
# 3  C 700 
# 4  D -600 

dcast表の形式を変更し、mutateは、新しい列を作成します。

1

data.tableを使用できます。 'data.frame'を 'data.table'(setDT(df1))に変換し、 'タイプ'が 'Y'の場合は '収入'を負の値に変換し、 'グループ'でグループ化して '収入'のsumを取得します。

library(data.table) 
setDT(df1)[Type == "Y", Income := -1 * Income][, .(Diff= sum(Income)) , Group] 
# Group Diff 
#1:  A 500 
#2:  B -500 
#3:  C 700 
#4:  D -600 

かとtidyr/dplyr

library(dplyr) 
library(tidyr) 
spread(df1, Type, Income, fill = 0) %>% 
       transmute(Group, Diff = X- Y) 
# Group Diff 
#1  A 500 
#2  B -500 
#3  C 700 
#4  D -600 
3

ベースRでこれを試してみてください:

aggregate(Diff~Group, 
      with(df, data.frame(Group=Group, Diff=ifelse(Type=="X", 1, -1)*Income)), sum) 

# Group Diff 
#1  A 500 
#2  B -500 
#3  C 700 
#4  D -600 

データ

df <- structure(list(Group = structure(c(1L, 1L, 2L, 2L, 3L, 4L), .Label = c("A", 
"B", "C", "D"), class = "factor"), Type = structure(c(1L, 2L, 
2L, 1L, 1L, 2L), .Label = c("X", "Y"), class = "factor"), Income = c(1000L, 
500L, 2000L, 1500L, 700L, 600L)), .Names = c("Group", "Type", 
"Income"), class = "data.frame", row.names = c(NA, -6L)) 
関連する問題