R:函数参数和lapply嵌套在函数中或使用data.table从外部函数调用

时间:2016-11-29 12:08:07

标签: r function arguments data.table lapply

data.table还是新手,并与环境合作。

我有data.table与此相似(虽然大得多):

mydt <- data.table(ID = c("a", "a", "a", "b", "b", "b"),
                   col1 = c(1, 2, 3, 4, 5, 6),
                   col2 = c(7, 8, 9, 10, 11, 12),
                   key = "ID")

我写了一个带mydt的函数,用它的键将它在data.table列表中拆分,然后在data.table列表中的每个表中取列,用户在参数中指定并将其乘以用户在另一个参数中提供的数字:

myfun <- function(data, constant, column) {
  data <- split(x = data, by = key(data))
  data <- lapply(data, function(i) {
    i[ , (column) := get(column)*constant]
  })
  return(data)
}

x <- myfun(data = mydt, constant = 3, column = "col1")

x

$a
   ID col1 col2
1:  a    3    7
2:  a    6    8
3:  a    9    9

$b
   ID col1 col2
1:  b   12   10
2:  b   15   11
3:  b   18   12

如果我正确理解R中的范围规则lapply将查看其所调用的环境,则会发现columnconstant作为myfun的参数提供并将使用它们。

但是,传递给lapply的函数比这里传递的函数要长得多,而且它将更多地用于除了分割data.table之外的许多其他函数。这就是为什么我想将此部件定义为将在其他函数中调用的外部函数。这就是我所做的:

split.dt <- function(data) {
  split(data, by = key(data))
}

mult <- function(data) {
  lapply(data, function(i) {
    i[ , (column) := get(column)*constant]
  })
}

myfun <- function(data, constant, column) {
  data <- split.dt(data = data)
  data <- mult(data = data)
}

x <- myfun(data = mydt, constant = 3, column = "col1")

返回错误:

Error in eval(expr, envir, enclos) : object 'column' not found

我尝试将column i[ , eval(column)] i[ , eval(column)]mult函数一起包裹parent.frame() parent.env()sys.call,但没有成功。最后,我找到了一个解决方案,我使用myfun来获取在列表中传递给mult的参数,并在split.dt <- function(data) { split(data, by = key(data)) } mult <- function(data) { supplied.col <- sys.call(which = -1)[["column"]] supplied.constant <- sys.call(which = -1)[["constant"]] lapply(data, function(i) { i[ , eval(supplied.col) := get(supplied.col)*supplied.constant] }) } myfun <- function(data, constant, column) { data <- split.dt(data = data) data <- mult(data = data) } x <- myfun(data = mydt, constant = 3, column = "col1") x $a ID col1 col2 1: a 3 7 2: a 6 8 3: a 9 9 $b ID col1 col2 1: b 12 10 2: b 15 11 3: b 18 12 中使用它们,如下所示:

mult

它确实有效,但我不确定是否:

  1. 这是正确或最有效的方法。让myfun查看提供给XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("cmn", "http://fake.com/schemas/common"); XmlSerializer serializer = new XmlSerializer(load.GetType()); serializer.Serialize(stringwriter, load, ns); 的参数的方法是什么?
  2. 如果函数包装在包中,这会起作用吗?

1 个答案:

答案 0 :(得分:2)

1)只需将columnconstant传递给mult作为其他参数。

mult <- function(data, constant, column) {
  lapply(data, function(i) {
    i[ , (column) := get(column)*constant]
  })
}

myfun <- function(data, constant, column) {
  data <- split.dt(data = data)
  data <- mult(data, constant, column)
}

2)或者将mult定义为:

mult <- function(data, envir = parent.frame()) with(envir, 
  lapply(data, function(i) {
    i[ , (column) := get(column)*constant]
  })
)

2a)

mult <- function(data, envir = parent.frame()) {
  constant <- envir$constant
  column <- envir$column
  lapply(data, function(i) {
    i[ , (column) := get(column)*constant]
  })
}