簡體   English   中英

使用dplyr將列名作為參數傳遞給函數

[英]Passing column name as parameter to a function using dplyr

我有一個如下數據框:

transid<-c(1,2,3,4,5,6,7,8)
accountid<-c(a,a,b,a,b,b,a,b)
month<-c(1,1,1,2,2,3,3,3)
amount<-c(10,20,30,40,50,60,70,80)
transactions<-data.frame(transid,accountid,month,amount)

我正在嘗試使用dplyr包動詞編寫每個accountid的每月總量的函數。

my_sum<-function(df,col1,col2,col3){
df %>% group_by_(col1,col2) %>%summarise_(total_sum = sum(col3))
}

my_sum(transactions, "accountid","month","amount")

要獲得如下結果:

accountid   month  total_sum
a            1       30
a            2       40
a            3       70
b            1       30
b            2       50
b            3       140

我得到的錯誤如下: - 總和錯誤(col3):參數的'type'(字符)無效。如何在匯總函數中將列名作為參數傳遞而不引用?

我建議以下解決方案:

my_sum <- function(df, col_to_sum,...) {

    col_to_sum <- enquo(col_to_sum)
    group_by <- quos(...)

    df %>%
        group_by(!!!group_by) %>%
        summarise(total_sum = sum(!!col_to_sum)) %>% 
        ungroup()
}

transactions %>% my_sum(amount, accountid, month)

結果

>> transactions %>% my_sum(amount, accountid, month)
# A tibble: 6 x 3
  accountid month total_sum
     <fctr> <dbl>     <dbl>
1         a     1        30
2         a     2        40
3         a     3        70
4         b     1        30
5         b     2        50
6         b     3       140

數據

在你的原始答案中,你已經通過了unqoted字符串,我已經使用Hmisc:Cs函數解決了這個問題,但原則上你應該用""來包圍你的字符串; 當然,除非你正在調用一些名為ab等的對象。 原始問題並不清楚。

使用數據:

transid <- c(1, 2, 3, 4, 5, 6, 7, 8)
accountid <- Hmisc::Cs(a, a, b, a, b, b, a, b)
month <- c(1, 1, 1, 2, 2, 3, 3, 3)
amount <- c(10, 20, 30, 40, 50, 60, 70, 80)
transactions <- data.frame(transid, accountid, month, amount)

筆記

  • 如果你看一下使用dplyr編程捕獲多變量部分 ,你會發現使用quos()函數解決了非常類似的問題。 實際上,您的任務是一個完美的例子,應該如何使用quos()函數。

  • 省略號...應該在結尾處,因為假設該函數將用於對具有多列的數據進行分組。 當然,如果需要,您可以enquo()列傳遞一列enquo()每列,依此類推,但使用...更自然,並且與上面鏈接的文章中討論的推薦解決方案一致。 請注意,這種方法會改變函數調用中參數的順序,因為...應該在最后。

  • 如果您使用的是summarise()則不必像我的示例那樣ungroup()數據。 例如代碼:

     mtcars %>% group_by(am) %>% summarise(mean_disp = mean(disp)) %>% mutate(am = am + 1) 

    將工作; 而代碼:

     mtcars %>% group_by(am) %>% mutate(am = am + 1) 

    將返回預期的錯誤:

    mutate_impl(.data,dots)中的錯誤:無法修改列am因為它是一個分組變量

    如果要mutate()原始數據或執行其他操作以保持分組變量不變,則應使用ungroup() 傳遞分組變量可能后來證明是有問題的,它會說它主要是你的dplyr工作流程中的品味/順序問題。 如果你和其他功能用戶要記住tibble可能攜帶分組變量那么就沒有問題; 就個人而言,我傾向於忘記這一點,所以如果我對攜帶分組變量不感興趣,我傾向於ungroup()數據。

你可以使用quo()將quosure對象作為參數傳遞,然后使用某種非引號函數懶惰地評估它們,在這個例子中我使用!!

library(tidyverse)
my_sum<-function(df,col1,col2,col3){
df %>% group_by(!!col1,!!col2) %>%summarise(total_sum = sum(!!col3))
}

my_sum(transactions, quo(accountid),quo(month),quo(amount))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM