R:在用户定义的函数中使用get和data.table

R:在用户定义的函数中使用get和data.table,r,data.table,user-defined-functions,R,Data.table,User Defined Functions,我正在学习如何在R中编写使用诸如data.table和dplyr等通用包的函数 我编写的这个函数计算某一特定类别的观察值在其他组中的百分比(例如:2015年发布的10-20mpg汽车的份额),并生成一个表。这里没有一个函数: library(data.table) library(scales) #Create test dataframe and cut off points test<-data.frame(x=c(0:10), y=c(rep(1,5),rep(2,6)), z=

我正在学习如何在R中编写使用诸如data.table和dplyr等通用包的函数

我编写的这个函数计算某一特定类别的观察值在其他组中的百分比(例如:2015年发布的10-20mpg汽车的份额),并生成一个表。这里没有一个函数:

library(data.table)
library(scales)


#Create test dataframe and cut off points
test<-data.frame(x=c(0:10), y=c(rep(1,5),rep(2,6)), z=c("A","A","A","B","B","B","C","C","C","C","C"))
test <- data.table(test)


#trial non function version (calculating share of row by category z): works
tmp<-test[,.(N=.N), keyby=.(y,z)]
tmp[,total:=sum(N), by=y]
tmp[,percent:=percent(N/total)]
dcast(tmp,y ~ z, value.var="percent")
库(data.table)
图书馆(比例尺)
#创建测试数据帧和截止点

test您不必在
dt
上调用
get
(根据我的经验,
get
最常用于使用字符串引用列),您可以通过
keyby
提供字符向量:

tw_tab <- function(dt,v1,v2){

    #set up variables as charaters
    v1<-as.character(substitute(v1))
    v2<-as.character(substitute(v2))

    #function
    tmp <- dt[,.(N=.N), keyby = c(v1, v2)]
    tmp[,total:=sum(N), by= c(v1)]
    tmp[,percent:=percent(N/total)]
    dcast(tmp, paste(v1, '~', v2), value.var="percent")
}

#test function
tw_tab(test, y, z)
#    y     A     B     C
# 1: 1 60.0% 40.0%    NA
# 2: 2    NA 16.7% 83.3%
我会

row_pct = function(DT, fm){
  all = all.vars(fm)
  lhs = all.vars(fm[[2]])
  rhs = all.vars(fm[[3]])

  DT[, .N, by=all][, 
    p := percent(N/sum(N)), by=lhs][, 
    dcast(.SD, eval(fm), value.var = "p", fill = percent(0))]
}
示例:

row_pct(test, y ~ z)

   y   A     B     C
1: 1 60%   40%    0%
2: 2  0% 16.7% 83.3%

row_pct(data.table(mtcars), cyl + gear ~ carb)

   cyl gear    1     2     3     4    6   8
1:   4    3 100%    0%    0%    0%   0%  0%
2:   4    4  50%   50%    0%    0%   0%  0%
3:   4    5   0%  100%    0%    0%   0%  0%
4:   6    3 100%    0%    0%    0%   0%  0%
5:   6    4   0%    0%    0%  100%   0%  0%
6:   6    5   0%    0%    0%    0% 100%  0%
7:   8    3   0% 33.3% 25.0% 41.7%   0%  0%
8:   8    5   0%    0%    0%   50%   0% 50%
如果出于某种原因,您希望分别输入行变量和列变量:

row_pct2 = function(DT, rowvars, colvar){
      fm  = substitute(`~`(rowvars, colvar))
      row_pct(DT, fm)
}

# Examples:
row_pct2(test, y, z)
row_pct2(data.table(mtcars), cyl + gear, carb)
仅供参考,
(N=.N)
.N
将执行相同的操作,因为这是默认名称。另外,在函数中,我猜keyby vs by不会获得任何结果。
row_pct(test, y ~ z)

   y   A     B     C
1: 1 60%   40%    0%
2: 2  0% 16.7% 83.3%

row_pct(data.table(mtcars), cyl + gear ~ carb)

   cyl gear    1     2     3     4    6   8
1:   4    3 100%    0%    0%    0%   0%  0%
2:   4    4  50%   50%    0%    0%   0%  0%
3:   4    5   0%  100%    0%    0%   0%  0%
4:   6    3 100%    0%    0%    0%   0%  0%
5:   6    4   0%    0%    0%  100%   0%  0%
6:   6    5   0%    0%    0%    0% 100%  0%
7:   8    3   0% 33.3% 25.0% 41.7%   0%  0%
8:   8    5   0%    0%    0%   50%   0% 50%
row_pct2 = function(DT, rowvars, colvar){
      fm  = substitute(`~`(rowvars, colvar))
      row_pct(DT, fm)
}

# Examples:
row_pct2(test, y, z)
row_pct2(data.table(mtcars), cyl + gear, carb)