【问题标题】:adding new columns to a data.table within a function in R在 R 中的函数内向 data.table 添加新列
【发布时间】:2020-07-29 02:43:36
【问题描述】:

作为更大功能的一部分,我需要在 data.table 中创建两个新列(稍后用于创建绘图)。

这些是我的专栏的名称:

names(freqSevDataAge)
 [1] "ag5"                           "claims"              "exposure"               
 [7] "severity"             "frequency" 

我正在尝试使这部分功能起作用:

  testDT <- function(data, xvar, yvar, yvarsec, groupvar, ...){

  freqSevDataAge2 <- freqSevDataAge[!claims == 0][, ':=' (scaled = "yvarsec" * max("yvar")/max("yvarsec"),
                                                          param  = max("yvar")/max("yvarsec"))]
  }

  testDT(freqSevDataAge, xvar = "ag5", yvar = "severity", yvarsec = "frequency", groupvar = "gender")

我得到的错误是:

“yvarsec”* max(“yvar”) 中的错误:二进制的非数字参数 运营商

编辑:

使用get() 提出的解决方案有效,但是现在我在使用 ggplot 中新创建的列时遇到了麻烦。我收到一个错误:

f(...) 中的错误:找不到对象“参数”

我通过stem检查了函数,知道param列已创建,问题是在ggplot中调用它。我怎么能

getSecPlot <- function(data, xvar, yvar, yvarsec, groupvar, ...){

  if ("agegroup" %in% xvar) xvar <- get("agegroup")

  data <- data[!claims == 0][, ':=' (scaled = get(yvarsec) * max(get(yvar))/max(get(yvarsec)),
                                     param  = max(get(yvar))/max(get(yvarsec)))]

param <- unique(param)

  sec_plot <- ggplot(data, aes_string (x = xvar, group = groupvar)) +
      geom_col(aes_string(y = yvar, fill = groupvar, alpha = 0.5), position = "dodge") +
      geom_line(aes(y = scaled,  color = gender)) +
      scale_y_continuous(sec.axis = sec_axis(~./(param),
                                             name = paste0("average ", yvarsec), labels = function(x) format(x, big.mark = " ", scientific = FALSE))) +
      labs(y = paste0("total ", yvar)) +
      theme_pubclean()
  }

【问题讨论】:

  • param &lt;- unique(param) 是错误的,因为param 是在data 中创建的,因此您可能需要param &lt;- unique(data$param)

标签: r function functional-programming data.table nse


【解决方案1】:

我们可以通过去掉函数内变量的引号来改变函数,使用get来获取对象的值

library(data.table)
testDT <- function(data, xvar, yvar, yvarsec, groupvar, ...){

   freqSevDataAge[!claims == 0][, ':=' 
    (scaled = get(yvarsec) * max(get(yvar))/max(get(yvarsec)),
                       param  = max(get(yvar))/max(get(yvarsec)))][]
    }


testDT(freqSevDataAge, xvar = "ag5", yvar = "severity", 
             yvarsec = "frequency", groupvar = "gender")
#    ag5 severity frequency gender claims     scaled     param
#1:   3        8         9      M      1  3.7500000 0.4166667
#2:   6        3        24      F      1 10.0000000 0.4166667
#3:   7       10        17      F      1  7.0833333 0.4166667
#4:   8        8         8      M      1  3.3333333 0.4166667
#5:  10       10         1      M      1  0.4166667 0.4166667

或者另一种选择是使用as.symbol 转换为符号并使用eval 进行评估

数据

set.seed(24)
freqSevDataAge <- data.table(ag5 = 1:10, severity = sample(1:10, 10,
   replace = TRUE), frequency = sample(1:24, 10, replace = TRUE),
   gender = sample(c("M", "F"), 10, replace = TRUE), 
   claims = sample(0:1, 10, replace = TRUE))

【讨论】:

  • 那是我最初所拥有的,但出现错误:` yvarsec * max(yvar) 中的错误:二进制运算符的非数字参数`
  • @Danka 你用过get
  • @Danka 你可以用输出检查我的可重现示例。也可能是您的某些列不是数字类
  • 我在帖子中添加了一个相关问题,也许你有想法?
猜你喜欢
  • 2017-06-22
  • 2012-07-03
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多