1313# ' @param edits_tbl an optional raw edits table used when 'df' is not supplied.
1414# ' Should contain 'user', 'date', 'action', 'key', 'tag'..
1515# ' @param tags_tbl an optional tags summary with columns 'key' and 'n' (counts)
16+ # ' @param max_names maximum number of names to include in the caption
1617# ' #'
1718# ' @returns a length-1 character vector containing the caption.
1819# ' @export
@@ -39,26 +40,26 @@ caption_group <- function(df = NULL,
3940 # ---- contribution frequency (changesets/day or edits/active-day) ----
4041 per_day <- NA_real_
4142 if (! is.null(contribs_tbl ) &&
42- all(c(" changesets" , " first_edit" , " last_edit" ) %in% base :: names(contribs_tbl ))) {
43- rng <- base :: range(c(contribs_tbl $ first_edit , contribs_tbl $ last_edit ), na.rm = TRUE )
44- days <- as.numeric(stats :: diff(rng )) + 1
45- total_changesets <- base :: sum(contribs_tbl $ changesets , na.rm = TRUE )
43+ all(c(" changesets" , " first_edit" , " last_edit" ) %in% names(contribs_tbl ))) {
44+ rng <- range(c(contribs_tbl $ first_edit , contribs_tbl $ last_edit ), na.rm = TRUE )
45+ days <- as.numeric(diff(rng )) + 1
46+ total_changesets <- sum(contribs_tbl $ changesets , na.rm = TRUE )
4647 per_day <- ifelse(days > 0 , total_changesets / days , total_changesets )
47- } else if (! is.null(df ) && " date" %in% base :: names(df )) {
48+ } else if (! is.null(df ) && " date" %in% names(df )) {
4849 # edits per active day
4950 per_day <- nrow(df ) / dplyr :: n_distinct(df $ date )
5051 }
5152
5253 freq <- dplyr :: case_when(
53- base :: is.na(per_day ) ~ " active" ,
54+ is.na(per_day ) ~ " active" ,
5455 per_day < 1 ~ " occasional" ,
5556 per_day < 10 ~ " frequent" ,
5657 TRUE ~ " heavy"
5758 )
5859
5960 # ---- activity type (creators / repairers / improvers) ----
6061 type_word <- " contributors"
61- if (! is.null(df ) && " action" %in% base :: names(df )) {
62+ if (! is.null(df ) && " action" %in% names(df )) {
6263 top_act <- df | >
6364 dplyr :: count(action , name = " n" ) | >
6465 dplyr :: arrange(dplyr :: desc(.data $ n )) | >
@@ -71,62 +72,62 @@ caption_group <- function(df = NULL,
7172 delete = " improvers" , remove = " improvers" ,
7273 .default = " contributors"
7374 )
74- } else if (! is.null(contribs_tbl ) && all(c(" adds" ," mods" ," dels" ) %in% base :: names(contribs_tbl ))) {
75- sums <- base :: colSums(contribs_tbl [, c(" adds" ," mods" ," dels" )], na.rm = TRUE )
76- type_word <- c(adds = " creators" , mods = " repairers" , dels = " improvers" )[base :: names(base :: which.max(sums ))]
75+ } else if (! is.null(contribs_tbl ) && all(c(" adds" ," mods" ," dels" ) %in% names(contribs_tbl ))) {
76+ sums <- colSums(contribs_tbl [, c(" adds" ," mods" ," dels" )], na.rm = TRUE )
77+ type_word <- c(adds = " creators" , mods = " repairers" , dels = " improvers" )[names(which.max(sums ))]
7778 }
7879
7980 # ---- experience level (avg edits per user) ----
8081 avg_edits <- NA_real_
81- if (! is.null(df ) && " user" %in% base :: names(df )) {
82+ if (! is.null(df ) && " user" %in% names(df )) {
8283 avg_edits <- df | >
8384 dplyr :: count(.data $ user , name = " n" ) | >
84- dplyr :: summarise(m = base :: mean(.data $ n )) | >
85+ dplyr :: summarise(m = mean(.data $ n )) | >
8586 dplyr :: pull(.data $ m )
86- } else if (! is.null(contribs_tbl ) && " total_edits" %in% base :: names(contribs_tbl )) {
87- avg_edits <- base :: mean(contribs_tbl $ total_edits , na.rm = TRUE )
87+ } else if (! is.null(contribs_tbl ) && " total_edits" %in% names(contribs_tbl )) {
88+ avg_edits <- mean(contribs_tbl $ total_edits , na.rm = TRUE )
8889 }
89- exp_level <- if (base :: is.na(avg_edits )) " hobbyists" else dplyr :: case_when(
90+ exp_level <- if (is.na(avg_edits )) " hobbyists" else dplyr :: case_when(
9091 avg_edits < 50 ~ " hobbyists" ,
9192 avg_edits < 500 ~ " pro-ams" ,
9293 TRUE ~ " professionals"
9394 )
9495
9596 # ---- interests (top 3 tag keys) ----
9697 top_tags <- character (0 )
97- if (! is.null(tags_tbl ) && all(c(" key" ," n" ) %in% base :: names(tags_tbl ))) {
98+ if (! is.null(tags_tbl ) && all(c(" key" ," n" ) %in% names(tags_tbl ))) {
9899 top_tags <- tags_tbl | >
99100 dplyr :: arrange(dplyr :: desc(.data $ n )) | >
100101 dplyr :: slice_head(n = 3 ) | >
101102 dplyr :: pull(.data $ key )
102- } else if (! is.null(df ) && any(c(" key" ," tag" ) %in% base :: names(df ))) {
103- tag_col <- if (" key" %in% base :: names(df )) " key" else " tag"
103+ } else if (! is.null(df ) && any(c(" key" ," tag" ) %in% names(df ))) {
104+ tag_col <- if (" key" %in% names(df )) " key" else " tag"
104105 top_tags <- df | >
105106 dplyr :: count(.data [[tag_col ]], name = " n" ) | >
106107 dplyr :: arrange(dplyr :: desc(.data $ n )) | >
107108 dplyr :: slice_head(n = 3 ) | >
108109 dplyr :: pull(1 )
109110 }
110- tags_text <- if (base :: length(top_tags )) base :: paste(top_tags , collapse = " , " ) else " a variety of features"
111+ tags_text <- if (length(top_tags )) paste(top_tags , collapse = " , " ) else " a variety of features"
111112
112113 # ---- homogeneity (Gini on edits/user) ----
113114 gini <- NA_real_
114- if (! is.null(df ) && " user" %in% base :: names(df )) {
115+ if (! is.null(df ) && " user" %in% names(df )) {
115116 v <- df | >
116117 dplyr :: count(.data $ user , name = " n" ) | >
117118 dplyr :: pull(.data $ n ) | >
118- base :: sort()
119- if (base :: length(v )) {
120- n <- base :: length(v )
121- gini <- (2 * base :: sum(seq_len(n ) * v ) / base :: sum(v ) / n ) - (n + 1 ) / n
119+ sort()
120+ if (length(v )) {
121+ n <- length(v )
122+ gini <- (2 * sum(seq_len(n ) * v ) / sum(v ) / n ) - (n + 1 ) / n
122123 }
123124 }
124- homog <- if (base :: is.na(gini )) " diverse" else if (gini > 0.6 ) " homogeneous"
125+ homog <- if (is.na(gini )) " diverse" else if (gini > 0.6 ) " homogeneous"
125126 else if (gini > 0.4 ) " somewhat concentrated" else " diverse"
126127
127128 # ---- final caption ----
128129 glue :: glue(
129130 " This is a {homog} group of {freq} {type_word}, mostly {exp_level}, with interests in {tags_text}."
130131 ) | >
131- base :: as.character()
132+ as.character()
132133}
0 commit comments