2016-05-16 5 views
2

私はグループとサブグループを持つ大きなデータフレームを持っています。私は、次のデータフレームのOUTPUT欄に示すように、各グループ内のサブグループのインデックスを決定したいと思います:私は成功せずに、いくつかの可能性を試してみたサブグループインデックスを決定する

df <- data.frame(
    Group = factor(c("A","A","A","A","A","B","B","B","B")), 
    Subgroup = factor(c("a","a","b","b","b","a","a","b","b")), 
    OUTPUT = c(1,1,2,2,2,1,1,2,2) 
) 

。私はdplyrと仕事をしたいと思いますが、これについてどうやって行くのか分かりません。次のコードは予期しない結果を返します。

require(dplyr) 

df <- df %>% 
    group_by(Group) %>% 
    mutate(
    OUTPUT_2 = dplyr::id(Subgroup) 
) 

#df 
# Group Subgroup OUTPUT_2 
# (fctr) (fctr) (int) 
#1  A  a  8 
#2  A  a  8 
#3  A  b  8 
#4  A  b  8 
#5  A  b  8 
#6  B  a  4 
#7  B  a  4 
#8  B  b  4 
#9  B  b  4 

私は近くにいると感じていますが、そこには到着しません。誰でも助けることができますか?

+1

によってグループ化した後、「サブグループ」のunique要素を持つmatchでは 'のようなものが必要ですas.numeric(サブグループ) '? – aosmith

答えて

2

我々はdplyr

library(dplyr) 
df %>% 
    group_by(Group) %>% 
    mutate(OUTPUT = as.numeric(factor(Subgroup, levels= unique(Subgroup)))) 
# Group Subgroup OUTPUT 
# <fctr> <fctr> <dbl> 
#1  A  a  1 
#2  A  a  1 
#3  A  b  2 
#4  A  b  2 
#5  A  b  2 
#6  B  a  1 
#7  B  a  1 
#8  B  b  2 
#9  B  b  2 

それとも別のオプションのfactorルートを使用することができる「グループ」

df %>% 
    group_by(Group) %>% 
    mutate(OUTPUT = match(Subgroup, unique(Subgroup))) 
# Group Subgroup OUTPUT 
# <fctr> <fctr> <int> 
#1  A  a  1 
#2  A  a  1 
#3  A  b  2 
#4  A  b  2 
#5  A  b  2 
#6  B  a  1 
#7  B  a  1 
#8  B  b  2 
#9  B  b  2 
+1

非常にいいです、ありがとうございました!あなたはそれがシンプルで実際には私が望むようにdplyrを含むので受け入れられます:-) – Ratnanil

1
library(data.table) 
dt = as.data.table(df) # or setDT to convert in place 

unique(dt[, .(Group, Subgroup)])[, idx := 1:.N, by = Group][dt, on = c('Group', 'Subgroup')] 
# Group Subgroup idx OUTPUT 
#1:  A  a 1  1 
#2:  A  a 1  1 
#3:  A  b 2  2 
#4:  A  b 2  2 
#5:  A  b 2  2 
#6:  B  a 1  1 
#7:  B  a 1  1 
#8:  B  b 2  2 
#9:  B  b 2  2 

dplyrへの翻訳は簡単です。


別の方法、aosmithさんのコメントからの要素を使用してのアイデア以下、次のとおりです。

dt[, idx := as.integer(factor(Subgroup, unique(Subgroup))), by = Group][] 

これはあなたは後にしているインデックスです。グループごとに正しいレベルの要因を作成します。ここで

2

が凝集することなくdata.tableとソリューションです:

dt[order(Subgroup), Output := cumsum(!duplicated(Subgroup)) , by = .(Group)] 

これは、集計に基づく方法に比べてはるかに高速になります。

+0

サブグループの要素がシャッフルされていると、これは機能しません。 OPデータの 'dt [6、Subgroup:= 'b']'を変更して、もう一度 – eddi

+0

@ eddiを試してみてください。これは 'setkey'で簡単に解決できます – Bulat

+2

Bulat、それは本当です。 'dt'の元の順序を崩していない' i'引数中の 'order(Subgroup)'と '*'は並べ替え(高価です)を避けるので非常に効率的です。 – Arun

関連する問題