[英]Aggregate by string column name in R
我想將data.frame中的數據分組為兩列,然后對特定的第三列求和。 例如:
> aggregate(mpg~gear+cyl, data=mtcars, FUN=sum)
gear cyl mpg
1 3 4 21.5
2 4 4 215.4
3 5 4 56.4
4 3 6 39.5
5 4 6 79.0
6 5 6 19.7
7 3 8 180.6
8 5 8 30.8
現在,我需要為不同的列多次執行此操作。 所以我想編寫一個概括它的函數。 它采用data.frame和其中一個列(為了簡單起見)並做同樣的事情。
agg.data <- function(df, colname) {
aggregate(mpg~gear+colname, data=df, FUN=sum)
}
運行這將產生:
Error in eval(expr, envir, enclos) : object 'colname' not found
如何將colname的值傳遞給聚合?
將公式的字符串表示粘貼在一起,並將該字符串作為參數傳遞給formula()...
agg.data <- function(df, colname) {
aggregate(formula(paste0("mpg~gear+", colname)), data=df, FUN=sum)
}
> agg.data(mtcars, "cyl")
gear cyl mpg
1 3 4 21.5
2 4 4 215.4
3 5 4 56.4
4 3 6 39.5
5 4 6 79.0
6 5 6 19.7
7 3 8 180.6
8 5 8 30.8
使用data.table
:
fun.dt <- function(dt, col) {
dt[, .(mpg=sum(mpg)), by=c("gear", col)]
}
require(data.table)
dt = as.data.table(mtcars)
fun.dt(dt, "cyl")
# gear cyl mpg
# 1: 4 6 79.0
# 2: 4 4 215.4
# 3: 3 6 39.5
# 4: 3 8 180.6
# 5: 3 4 21.5
# 6: 5 4 56.4
# 7: 5 8 30.8
# 8: 5 6 19.7
除了列/表達式列表之外, data.tables中的by
表達式還可以采用列名的字符向量。 我們可以簡單地為by
參數提供一個字符向量。
您可以輕松使用“常規” aggregate
接口(即不是公式接口)來提供變量中的列名稱。 語法稍有不同,但仍然很容易,不需要粘貼:
agg.data2 <- function(df, colname) {
aggregate(df[["mpg"]], list(df[["gear"]], df[[colname]]), FUN=sum)
}
agg.data2(mtcars, "cyl")
# Group.1 Group.2 x
#1 3 4 21.5
#2 4 4 215.4
#3 5 4 56.4
#4 3 6 39.5
#5 4 6 79.0
#6 5 6 19.7
#7 3 8 180.6
#8 5 8 30.8
這是dplyr的等價物:
library(dplyr)
agg.data.dplyr <- function(df, colname) {
df %>%
group_by_(.dots = c("gear", colname)) %>%
summarise(sum = sum(mpg)) %>%
ungroup()
}
agg.data.dplyr(mtcars, "cyl")
您還可以使用deparse
和substitute
傳遞未加引號的列名
agg.data <- function(df, colname) {
aggregate(df$mpg, list(df$gear, df[, deparse(substitute(colname))]), FUN=sum)
}
agg.data(mtcars, cyl)
# Group.1 Group.2 x
# 1 3 4 21.5
# 2 4 4 215.4
# 3 5 4 56.4
# 4 3 6 39.5
# 5 4 6 79.0
# 6 5 6 19.7
# 7 3 8 180.6
# 8 5 8 30.8
您也可以使用ggplot
的樣式或者with
它來允許您只是按原樣編寫類名,而不使用substitute
傳遞字符串。
agg.data3 = function (df, colname){
colname = substitute(colname)
colname = as.character(colname)
aggregate(formula(paste0("mpg~gear+", colname)), data=mtcars, FUN=sum)
}
用法
agg.data3(cars, cyl)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.