使用“数据”参数编写长函数

时间:2019-04-29 02:15:07

标签: r

我知道如何使用data参数(How to handle "data" argument in a function?)编写短函数-您可以复制并粘贴函数主体,并使用if-else语句运行函数的功能取决于是否为“数据”参数提供了参数。我的功能更长,我不想复制并粘贴整个内容,而不想使用if语句来更改整个功能中的代码。

例如:

df <- data.frame(x = c(1:5), y = c(4:8), z = c(5:1))
my_fxn <- function(x, y, z, data) {
  aaa <- x ^ 2 + 5
  bbb <- (y * log(y) + 5) ^ 7
  ccc <- z + aaa
  ddd <- mean(c(x, y, z))
  eee <- aaa + bbb + ccc + ddd
  paste(eee, "my_fxn", eee, sep = "_")
}
my_fxn(df$x, df$y, df$z)
> my_fxn(df$x, df$y, df$z)
[1] "14500329.5724518_my_fxn_14500329.5724518" "64360436.579237_my_fxn_64360436.579237"   "240475836.750078_my_fxn_240475836.750078"
[4] "776392986.326892_my_fxn_776392986.326892" "2219080769.50416_my_fxn_2219080769.50416"

如何才能在my_fxn的开头简洁地编写一行(或几行)代码,以允许我使用以下代码行从my_fxn生成相同的答案? / p>

my_fxn(x, y, z, data = df)

更新:我认为我真正的问题是数据框架的名称和数据框架中的列与函数自变量的名称不匹配。为什么以下代码不起作用?

df <- data.frame(x = c(1:5), y = c(6:10), z = LETTERS[1:5])
my_fxn <- function (aaa, bbb, ccc, data) {
  if (!missing(data)) {
    aaa = as.numeric(data$aaa)
    bbb = as.numeric(data$bbb)
    ccc = as.character(data$ccc)
  }
  print(aaa[1])
}
my_fxn(x, y, z, df)

2 个答案:

答案 0 :(得分:1)

为什么需要复制并粘贴整个功能?您是否会使用与链接的SO线程相同的方法。也就是说,只需在代码的顶部指定x, y and z等于数据

df <- data.frame(x = c(1:5), y = c(4:8), z = c(5:1))
my_fxn <- function(x, y, z, data) {

  if(missing(data)){
    x = x; y = y; z = z # unnecessary but just to be explicit
  } else {
    x = data$x
    y = data$y
    z = data$z
  }

  aaa <- x ^ 2 + 5
  bbb <- (y * log(y) + 5) ^ 7
  ccc <- z + aaa
  ddd <- mean(c(x, y, z))
  eee <- aaa + bbb + ccc + ddd
  paste(eee, "my_fxn", eee, sep = "_")
}
 my_fxn(df$x, df$y, df$z)
[1] "14500329.5724518_my_fxn_14500329.5724518" "64360436.579237_my_fxn_64360436.579237"   "240475836.750078_my_fxn_240475836.750078" "776392986.326892_my_fxn_776392986.326892"
[5] "2219080769.50416_my_fxn_2219080769.50416"

> my_fxn(x, y, z, data = df)
[1] "14500329.5724518_my_fxn_14500329.5724518" "64360436.579237_my_fxn_64360436.579237"   "240475836.750078_my_fxn_240475836.750078" "776392986.326892_my_fxn_776392986.326892"
[5] "2219080769.50416_my_fxn_2219080769.50416"

因此,在您进行更新时,您正在尝试分配

aaa = as.numeric(data$aaa)
bbb = as.numeric(data$bbb)
ccc = as.character(data$ccc)

其中data$aaa将是data$x,而data$bbb将是data$y。这里的问题是,没有理由将x列与aaa关联,这就是为什么在我之前的答案中我使用x, y, z的原因。就您而言,该函数将查找当前不存在的df$aaa

为了按照您想要的方式进行概括,以使您无需知道列名并将其硬编码到函数中,可以尝试

my_fxn <- function (aaa, bbb, ccc, data) {
  if (!missing(data)) {
    aaa = as.numeric(data[,1])
    bbb = as.numeric(data[,2])
    ccc = as.character(data[,3])
  }
  print(aaa[1])
}
my_fxn(x, y, z, df)

答案 1 :(得分:0)

最简单的解决方法是将列名称作为字符传递给函数并修改函数,以便它从数据框列中获取值。

df <- data.frame(x = c(1:5), y = c(4:8), z = c(5:1))
my_fxn <- function(xx, yy, zz, data) {
  if(missing(data)){
    x = xx; y = yy; z = zz 
  } else {
  x <- data[[xx]]
  y <- data[[yy]]
  z <- data[[zz]]
  }

  aaa <- x ^ 2 + 5
  bbb <- (y * log(y) + 5) ^ 7
  ccc <- z + aaa
  ddd <- mean(c(x, y, z))
  eee <- aaa + bbb + ccc + ddd
  paste(eee, "my_fxn", eee, sep = "_")
}

my_fxn("x", "y", "z", data = df)
# [1] "14500329.5724518_my_fxn_14500329.5724518" "64360436.579237_my_fxn_64360436.579237"   
# [3] "240475836.750078_my_fxn_240475836.750078" "776392986.326892_my_fxn_776392986.326892"
# [5] "2219080769.50416_my_fxn_2219080769.50416"