在第二个 R 函数中调用通过一个 R 函数提示的用户输入

Calling user inputs prompted through one R function in a second R function

非常感谢您提前帮助我 - 我是 R 编程的新手,并且一直试图在另一个函数中使用通过一个函数接受的用户输入。第二个函数是一个简单的工资计算器,其中三个变量是小时数、每小时工资率和工作小时数超过 180 时工资率的乘积次数。我编写了一个名为 enterval 的第一个函数,通过它我我要求用户输入上述变量。在称为薪水的第二个函数中,我试图在 运行 支付计算之前使用 enterval 接受输入。我被卡住了,因为当我遇到 "if" 条件时,第二个函数 salary 中断了,指定 h > 180。我在下面分享我的代码。再次感谢您的帮助。我在之前的答案中进行了搜索,但找不到能够完全回答我的查询的特定实例 - 如果我错过了之前的适当回复,我深表歉意。 我在 运行 此代码中遇到的错误是“h > 180 中的错误: 比较 (6) 仅适用于原子类型和列表类型

enterval <- function()  {
h <- (readline("Please enter number of hours: "))
h <- as.integer(h)
r <- (readline("Please enter applicable rate: "))
r <- as.integer(r)
m <- (readline("Please confirm your multiplier: "))
m <- as.integer(m)
}
salary <- function ()  {
    enterval()
    if (h > 180)  {
        totalpay <- (180*r) + ((h-180)*r*m)
        }
    else  {
        totalpay <- (h*r)
        }
    totalpay
}

我认为你需要的是这样的功能:

enterval <- function()  {
  h <- (readline("Please enter number of hours: "))
  h <- as.numeric(h)
  r <- (readline("Please enter applicable rate: "))
  r <- as.numeric(r)
  m <- (readline("Please confirm your multiplier: "))
  m <- as.numeric(m)
  list(h=h, r=r, m=m)
}

salary <- function ()  {
  inputs <- enterval()
  if (inputs$h > 180)  {
    totalpay <- (180*inputs$r) + ((inputs$h-180)*inputs$r*inputs$m)
  }
  else  {
    totalpay <- (inputs$h*inputs$r)
  }
  totalpay
}

输出:

> salary()
Please enter number of hours: 5
Please enter applicable rate: 0.5
Please confirm your multiplier: 2
[1] 2.5

在您的问题中,enterval 只是 return 编辑了存储在 m 中的值,但即便如此也没有保存在任何地方(因为您没有将其分配给 salary 所以它不能被 salary 使用。在 R 函数中 return 只有最后一个对象(或者函数 return returns 如果使用的话)。在上面的函数我 return 一个包含元素 hrm.

的列表

然后我将该列表保存到 inputs,供 salary 使用。可以使用 $ 运算符访问 inputs 中的元素。

此外,作为一个小的补充,当你说比率时,我相信它是一个介于 0-1 之间的数字,所以我将 as.integer 更改为 as.numeric 因为 as.integer 将向下舍入为整数。如果您确实需要整数,请随意将其改回 as.integer

编辑

更好,可能更高级的写作方式salary

根据@RichardScriven 的评论,避免键入所有 input$* 变量的一个好方法是像这样使用 list2env

salary <- function ()  {
  inputs <- enterval()
  list2env(inputs, environment())
  if (h > 180)  {
    totalpay <- (180*r) + (h-180)*r*m)
  }
  else  {
    totalpay <- (h*r)
  }
  totalpay
}

list2env 实质上会在 salary 环境中的列表元素之外创建变量,无需使用 input$* 即可立即访问这些变量。

在 R 函数中赋值的变量(类似于许多其他编程语言)具有有限的范围,这意味着您在函数中赋值的 m 仅在该函数中可用。如果您希望您的变量在函数之外可用,您有两个主要选择:

  1. Return 变量,这是首选选项,它更清晰,并且是良好的编程实践,因为许多堆栈溢出 post 中描述的原因很多。要记住的重要一点是一个函数只能 return 一个变量。

  2. 您可以进行全局赋值,这将使您函数中的变量具有全局作用域,并且可以在所有函数中访问。代码是 m <<- 1 而不是 m <- 1。出于各种原因,不建议这样做。有关此主题的更多信息,请参阅 Global variables in R or Global and local variables in R

由于您只能 return 一个变量,您可以将所有三个对象放入一个数据框或列表中,然后 return 那个。尽管我会质疑您是否希望在函数中完成值输入。此外,如果您的用户输入对您的目标至关重要,那么 R 可能不是正确的语言。话虽这么说,下面的代码完成了你正在寻找的东西

enterval <- function()  {
  h <- (readline("Please enter number of hours: "))
  h <- as.integer(h)
  r <- (readline("Please enter applicable rate: "))
  r <- as.integer(r)
  m <- (readline("Please confirm your multiplier: "))
  m <- as.integer(m)
  salaryVariables <- data.frame("hours" = h, "rate" = r, "multiplier" = m)
  return(salaryVariables)
}
salary <- function(salaryInfo)  {
  r <- salaryInfo$rate
  h <- salaryInfo$hours
  m <- salaryInfo$multiplier
  if (h > 180)  {
    totalpay <- (180*r) + ((h-180)*r*m)
  }
  else  {
    totalpay <- (h*r)
  }
  return(totalpay)
}

mySalary <- enterval()
salary(mySalary)