كيف رقم/تسمية بيانات الجدول من قبل المجموعة عدد من group_by?

StackOverflow https://stackoverflow.com//questions/23026145

  •  21-12-2019
  •  | 
  •  

سؤال

لدي tbl_df حيث أريد أن group_by(u, v) لكل متميزة صحيح مزيج لوحظ مع (u, v).


تحرير: وحلت هذه المشكلة عن طريق إضافة group_indices() مرة أخرى في dplyr 0.4.0


أ) ثم تريد تعيين كل مجموعة متميزة بعض التعسفي متميزة عدد التسمية=1,2,3...على سبيل المثالمزيج (u,v)==(2,3) يمكن الحصول على التسمية 1, (1,3) يمكن الحصول على 2 ، وهلم جرا.كيف نفعل هذا مع أحد mutate(), دون ثلاث خطوات تلخيص و الذاتي الانضمام ؟

dplyr أنيق وظيفة n(), ولكن هذا يعطي عدد من العناصر داخل المجموعة وليس العام عدد المجموعة. في data.table وهذا من شأنه أن يسمى ببساطة .GRP.

ب) في الواقع ما كنت حقا ترغب في تعيين سلسلة/تسمية شخصية ('A','B',...).ولكن ترقيم مجموعات من الاعداد الصحيحه هي جيدة بما فيه الكفاية لأنني ثم يمكن استخدام integer_to_label(i) كما أدناه.ما لم يكن هناك طريقة ذكية لدمج هذين ؟ ولكن لا تقلق هذا الجزء.

set.seed(1234)

# Helper fn for mapping integer 1..26 to character label
integer_to_label <- function(i) { substr("ABCDEFGHIJKLMNOPQRSTUVWXYZ",i,i) }

df <- tbl_df(data.frame(u=sample.int(3,10,replace=T), v=sample.int(4,10,replace=T)))

# Want to label/number each distinct group of unique (u,v) combinations
df %>% group_by(u,v) %>% mutate(label = n()) # WRONG: n() is number of element within its group, not overall number of group

   u v
1  2 3
2  1 3
3  1 2
4  2 3
5  1 2
6  3 3
7  1 3
8  1 2
9  3 1
10 3 4

KLUDGE 1: could do df %>% group_by(u,v) %>% summarize(label = n()) , then self-join
هل كانت مفيدة؟

المحلول

تحديث الإجابة

get_group_number = function(){
    i = 0
    function(){
        i <<- i+1
        i
    }
}
group_number = get_group_number()
df %>% group_by(u,v) %>% mutate(label = group_number())

يمكنك أيضا أن تنظر في ما يلي قليلا غير قابل للقراءة الإصدار

group_number = (function(){i = 0; function() i <<- i+1 })()
df %>% group_by(u,v) %>% mutate(label = group_number())

باستخدام iterators حزمة

library(iterators)

counter = icount()
df %>% group_by(u,v) %>% mutate(label = nextElem(counter))

نصائح أخرى

dplyr لديه group_indices() الوظيفة التي يمكنك استخدامها مثل هذا:

df %>% 
    mutate(label = group_indices(., u, v)) %>% 
    group_by(label) ...

نهج آخر باستخدام data.table سيكون

require(data.table)
setDT(df)[,label:=.GRP, by = c("u", "v")]

مما يؤدي إلى:

    u v label
 1: 2 1     1
 2: 1 3     2
 3: 2 1     1
 4: 3 4     3
 5: 3 1     4
 6: 1 1     5
 7: 3 2     6
 8: 2 3     7
 9: 3 2     6
10: 3 4     3

تحديث جوابي مع ثلاث طرق مختلفة:

أ) أنيق غير dplyr الحل باستخدام interaction(u,v):

> df$label <- factor(interaction(df$u,df$v, drop=T))
 [1] 1.3 2.3 2.2 2.4 3.2 2.4 1.2 1.2 2.1 2.1
 Levels: 2.1 1.2 2.2 3.2 1.3 2.3 2.4

> match(df$label, levels(df$label)[ rank(unique(df$label)) ] )
 [1] 1 2 3 4 5 4 6 6 7 7

ب) جعل راندي أنيق سريعة وقذرة مولد-وظيفة الإجابة أكثر إحكاما:

get_next_integer = function(){
  i = 0
  function(u,v){ i <<- i+1 }
}
get_integer = get_next_integer() 

df %>% group_by(u,v) %>% mutate(label = get_integer())

ج) أيضا هنا هو بطانة واحدة باستخدام وظيفة مولد استغلال عالمي تعيين متغير من هذا:

i <- 0
generate_integer <- function() { return(assign('i', i+1, envir = .GlobalEnv)) }

df %>% group_by(u,v) %>% mutate(label = generate_integer())

rm(i)

ليس لدي ما يكفي من سمعة تعليق, لذلك أنا نشر إجابة بدلا من ذلك.

الحل باستخدام معامل() هو جيد جدا ولكن لا بد أن المجموعة يتم تعيين أرقام بعد (عامل) alphabetizes مستوياته.نفس السلوك يحدث مع dplyr هو group_indices().ربما كنت ترغب في مجموعة الأعداد المسندة من 1 إلى n استنادا إلى المجموعة الحالية من أجل.في هذه الحالة يمكنك استخدام:

my_tibble %>% mutate(group_num = as.integer(factor(group_var, levels = unique(.$group_var))) )
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top