非常感谢您的帮助-我是R编程的新手,一直在尝试在另一个函数中使用通过一个函数接受的用户输入。第二个函数是一个简单的工资计算器,其中三个变量是小时数、每小时工资率和工作小时数超过180时工资率的乘积。我已经编写了第一个名为enterval的函数,通过它我要求用户输入上面的变量。在第二个名为salary的函数中,我试图在运行支出计算之前使用enterval来接受输入。我被卡住了,因为当我达到一个"if"条件,指定h>180时,第二个函数salary就坏了。我在下面分享我的代码。再次感谢您的帮助。我在之前的答案中进行了搜索,但找不到一个完全回答我问题的具体例子——如果我错过了之前的适当回答,我深表歉意。我在运行此代码时遇到的错误是"错误in 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
只是返回了存储在m
中的值,但即使是这个值也没有保存在任何位置(因为您没有将其分配给salary
中的变量,所以salary
无法使用它。在R中,函数只返回最后一个对象(或者如果使用了函数return
,则返回什么)。在上面的函数中,我返回一个包含元素h
、r
和m
的列表。
然后我将该列表保存到inputs
,salary
可以使用该列表。可以使用$
运算符访问inputs
中的元素。
另外,作为一个小加法,当你说rate时,我相信它是一个介于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只能在该函数中使用。如果你想让你的变量在函数之外可用,你有两个主要的选择:
-
返回变量,这是首选选项,它更干净,是很好的编程实践,原因很多,在许多堆栈溢出帖子中都有描述。需要记住的一件重要事情是,一个函数只能返回一个变量。
-
您可以进行全局赋值,这将使函数中的变量具有全局范围,并且可以在所有函数中访问。这方面的代码是
m <<- 1
,而不是m <- 1
。由于各种原因,不建议这样做。有关此主题的更多信息,请参阅R中的全局变量或R中的整体和局部变量。
由于只能返回一个变量,因此可以将所有三个对象放入数据帧或列表中并返回。尽管我会质疑您是否希望在函数中完成值输入。此外,如果你的用户输入是你目标的主要内容,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)