2016-12-28 1 views
1

У меня возникли проблемы с использованием dplyr и group_by в функции вызова функции.group_by dplyr в функции NSE

Воспроизводимого Пример:

Используя следующие данные:

ex_data<- structure(list(word1 = c("no", "not", "not", "no", "not", "not", 
"not", "not", "no", "not", "no", "not", "not", "not", "no", "not", 
"no", "no", "not", "not", "not", "no", "not", "without", "never", 
"no", "not", "no", "no", "not", "not", "not", "no", "no", "no", 
"not", "not", "without", "never", "no", "not", "not", "not", 
"not", "not", "never", "no", "no", "not", "not"), word2 = c("doubt", 
"like", "help", "no", "want", "wish", "allow", "care", "harm", 
"sorry", "great", "leave", "pretend", "worth", "pleasure", "love", 
"danger", "want", "afraid", "doubt", "fail", "good", "forget", 
"feeling", "forget", "matter", "avoid", "chance", "hope", "forgotten", 
"miss", "perfectly", "bad", "better", "opportunity", "admit", 
"fair", "delay", "failed", "wish", "dislike", "distress", "refuse", 
"regret", "trust", "want", "evil", "greater", "better", "blame" 
), score = c(-1L, 2L, 2L, -1L, 1L, 1L, 1L, 2L, -2L, -1L, 3L, 
-1L, -1L, 2L, 3L, 3L, -2L, 1L, -2L, -1L, -2L, 3L, -1L, 1L, -1L, 
1L, -1L, 2L, 2L, -1L, -2L, 3L, -3L, 2L, 2L, -1L, 2L, -1L, -2L, 
1L, -2L, -2L, -2L, -2L, 1L, 1L, -3L, 3L, 2L, -2L), n = c(102L, 
99L, 82L, 60L, 45L, 39L, 36L, 23L, 22L, 21L, 19L, 18L, 18L, 17L, 
16L, 16L, 15L, 15L, 15L, 14L, 14L, 13L, 13L, 13L, 12L, 12L, 12L, 
11L, 11L, 10L, 10L, 10L, 9L, 9L, 9L, 9L, 9L, 9L, 8L, 8L, 8L, 
8L, 8L, 8L, 8L, 7L, 7L, 7L, 7L, 7L), contribution = c(-102L, 
198L, 164L, -60L, 45L, 39L, 36L, 46L, -44L, -21L, 57L, -18L, 
-18L, 34L, 48L, 48L, -30L, 15L, -30L, -14L, -28L, 39L, -13L, 
13L, -12L, 12L, -12L, 22L, 22L, -10L, -20L, 30L, -27L, 18L, 18L, 
-9L, 18L, -9L, -16L, 8L, -16L, -16L, -16L, -16L, 8L, 7L, -21L, 
21L, 14L, -14L)), .Names = c("word1", "word2", "score", "n", 
"contribution"), row.names = c(NA, -50L), class = c("tbl_df", 
"tbl", "data.frame")) 

Регулярной типичная операция трубопроводов работает, как ожидалось:

outside_result<- ex_data %>% 
    mutate(word2=reorder(word2,contribution)) %>% 
    group_by(word1) %>% 
    top_n(10,abs(contribution)) %>% 
    group_by(word1,word2) %>% 
    arrange(desc(contribution)) %>% 
    ungroup() %>% 
    mutate(word2 = factor(paste(word2,word1, sep = "__"), 
           levels=rev(paste(word2,word1,sep="__")))) 

Я реализовал выше в функция, приведенная ниже:

order_bars <- function(df,facetPanel,barCategory,value){ 
     df %>% mutate(barCategory=reorder(barCategory,value)) %>% 
      group_by(facetPanel) %>% 
      top_n(10,abs(value)) %>% 
      group_by(facetPanel,barCategory) %>% 
      arrange(desc(value)) %>% 
      ungroup() %>% 
      mutate(barCategory = factor(paste(barCategory,facetPanel, sep = "__"), 
            levels=rev(paste(barCategory,facetPanel,sep="__")))) 
     } 

И принимая советы от этой post, используется $ обозначения при обращении переменных в data.frame во время операций изменения в рамках функции.

inside_result<-order_bars(ex_data,ex_data$word1,ex_data$word2,ex_data$contribution) 

R выдает следующее сообщение об ошибке:

Error: unknown variable to group by : facetPanel 
Called from: resolve_vars(new_groups, tbl_vars(.data)) 

я подозреваю group_by потребности быть переделана, чтобы взять либо переменные с именем, или я должен использовать .dot обозначения для ссылки на столбцы, хотя я просто бросал на это на ветер ...

ответ

2

Вам нужно узнать, как использовать 1) версию SE от dplyr глаголов, таких как group_by_ и mutate_ и 2) загадочный lazyeval::interp. Пожалуйста, внимательно прочитайте vignette("nse").

Тогда мы можем прийти к:

order_bars <- function(df, facetPanel, barCategory, value){ 
    require(lazyeval) 
    df %>% 
    mutate_(barCategory = interp(~reorder(x, y), x = as.name(barCategory), 
           y = as.name(value))) %>% 
    group_by_(facetPanel) %>% 
    filter_(interp(~min_rank(desc(abs(x))) <= 10, x = as.name(value))) %>% 
    group_by_(facetPanel, barCategory) %>% 
    arrange_(interp(~desc(x), x = as.name(value))) %>% 
    ungroup() %>% 
    mutate_(barCategory = interp(
     ~factor(paste(x, y, sep = "__"), levels = rev(paste(x, y, sep = "__"))), 
     x = as.name(barCategory), y = as.name(facetPanel))) 
} 

order_bars(ex_data, 'word1', 'word2', 'contribution') 
# A tibble: 25 × 6 
    word1 word2 score  n contribution barCategory 
    <chr> <chr> <int> <int>  <int>  <fctr> 
1 not  like  2 99   198 like__not 
2 not  help  2 82   164 help__not 
3  no great  3 19   57 great__no 
4  no pleasure  3 16   48 pleasure__no 
5 not  love  3 16   48 love__not 
6 not  care  2 23   46 care__not 
7 not  want  1 45   45 want__not 
8 not  wish  1 39   39 wish__not 
9  no  good  3 13   39  good__no 
10 not allow  1 36   36 allow__not 

Обратите внимание, что мы должны заменить top_n с filter_ заявлением, поскольку ни top_n_ не существует. Глядя на источник top_n, очевидно, что должен быть построен оператор filter_.

Или, если вы хотите получить фантазии, вы можете написать NSE версию order_bars:

order_bars <- function(df,facetPanel,barCategory,value){ 
    facetPanel <- substitute(facetPanel) 
    barCategory <- substitute(barCategory) 
    value <- substitute(value) 

    require(lazyeval) 
    df %>% 
    mutate_(barCategory = interp(~reorder(x, y), x = barCategory, y = value)) %>% 
    group_by_(facetPanel) %>% 
    filter_(interp(~min_rank(desc(abs(x))) <= 10, x = value)) %>% 
    group_by_(facetPanel, barCategory) %>% 
    arrange_(interp(~desc(x), x = value)) %>% 
    ungroup() %>% 
    mutate_(barCategory = interp(
     ~factor(paste(x, y, sep = "__"), levels = rev(paste(x, y, sep = "__"))), 
     x = barCategory, y = facetPanel)) 
} 

order_bars(ex_data, word1, word2, contribution) 

В идеале, вы должны написать только версию SE полностью, и связать версию NSE версии SE с lazyeval , Я оставлю это как упражнение для читателя.

+0

это первый раз, когда я столкнулся с SE, и это хорошая возможность обучения ... спасибо за направление! –

+0

awwww Хороший ответ axeman, но человек, что оценка оценки SE ужасна –

+1

@Noobie, Да, один платит за красивую (по-моему) NSE с уродством (на мой взгляд) SE при использовании tidyverse. – Axeman