使 readline 等待 R 中的输入

Make readline wait for input in R

提问人:Hack-R 提问时间:11/25/2014 最后编辑:Hack-R 更新时间:8/12/2022 访问量:30835

问:

我试图让我的代码在继续之前要求我输入“TRUE”或“FALSE”值。

如果我一次运行一行,它目前工作正常,但是当我在 RStudio 中一次运行所有代码时,它只是在不等待用户输入的情况下继续,并为我的参数记录值“”。

raw <- readline("TRUE or FALSE -- this is a validation run: ")


if (raw == "F" | raw == "FALSE" | raw == "False"){
validation <- F
} else{
  validation <- T
}
rm(raw)

理想情况下,无论我如何在 RStudio 中-- ,运行它,或者运行它(即选择代码并按下或 ctrl-enter),我都想要一个有效的答案。RScriptsourcerun

r

评论

0赞 rawr 11/25/2014
您可以检查 f/F/false/False/FALSE/fasle/etc 的所有可能性if (toupper(unlist(strsplit(raw, ''))[1]) == 'F')
2赞 IRTFM 11/25/2014
注意:仅适用于交互模式。readline
0赞 Hack-R 11/25/2014
@BondedDust啊,好吧,那我需要吗?readLines
1赞 IRTFM 11/25/2014
readLines未设置提示。您需要描述如何使用它。使用 Rscript 不同于交互式使用。您需要回答第一个评论问题。如果您“在 RStudio 中”,那么大多数人会认为它是交互式控制台使用。只是不要假设你可以将它与 Rscript 一起使用或从系统命令行运行。
0赞 Hack-R 11/25/2014
@BondedDust 好吧,我现在就像我说的那样在 RStudio 中,尽管我当然想要一个对任何这些运行方式都健壮的解决方案。这不可能吗?

答:

32赞 IRTFM 11/25/2014 #1

如果你想在交互模式下执行此操作,那么你已经有了答案,但不能与 Rscript 一起使用。对于该实例,您需要使用以下命令向控制台发送消息:cat

如果此测试文件名为“prompt.r”,并且位于您在系统控制台会话中工作的目录中:

cat("a string please: ");
a <- readLines("stdin",n=1);
cat("You entered")
 str(a);
cat( "\n" )

然后,您可以从命令行运行它,如下所示

$ Rscript prompt.r

如果你想要一个通用的脚本,那么这将在交互式条件下运行你的脚本,而我的脚本则用于非交互式条件:

if (interactive() ){raw <- 
             readline("TRUE or FALSE -- this is a validation run: ")

                if (raw == "F" | raw == "FALSE" | raw == "False"){
               validation <- F
                 } else{
                     validation <- T
                       }
           rm(raw)  } else{
#  non-interactive
cat("a string please: ");
a <- readLines("stdin",n=1);
cat("You entered")
 str(a);
cat( "\n" )}

评论

0赞 jtianling 11/1/2017
有没有更好的方法将交互模式和脚本模式结合起来?
0赞 IRTFM 11/2/2017
对“更好”解决方案请求的回答需要某种当前尚未表达的软件指标。
2赞 jtianling 11/2/2017
不知道你是什么意思,至少在python和ruby中,你不需要把两者分开。
0赞 IRTFM 8/30/2022
如果你的软件指标是“像Python或Ruby一样做”,那么我看不出有什么方法可以满足这个请求。R具有“人格分裂”。有些函数在交互模式下工作,有些函数不工作。 R 依赖于特定于操作系统的系统级函数进行控制台交互,这些函数与脚本模式下的输入/输出不同。您可能希望将 OR 作为替代者。littlerShiny
19赞 Sohum Daftary 8/23/2016 #2

是否通过突出显示行并单击“运行”来运行代码?如果是这样,那可能是你的问题,因为 R 在终端中逐行输入你的代码。

相反,编写脚本(或注释掉未测试的部分)并单击源代码按钮。然后 R 等待用户响应,而不是将 readline() 之后的行输入到 readline() 中。

我和你有同样的问题,这促使我寻找答案。但后来我尝试了这种不同的代码执行方法,它奏效了。

评论

0赞 Richard Lusch 2/23/2017
这实际上解决了我的问题,只要原始代码正在获取,readLines() 似乎就会停止并等待用户输入。
0赞 IRTFM 8/30/2022
是的,但是 Hack-R 说他想要一个支持 Rscript 的答案,并且在某些 IDE 中使用“Source”按钮不是这样。
4赞 Billy Raseman 7/17/2021 #3

虽然它需要交互模式,但我发现 utils 包中的函数为 TRUE/FALSE(或更准确地说是/否)问题提供了一个漂亮、简单的用户界面。例如,以下代码将生成以下对话框。askYesNo()

Yes No Dialog

  • 是的,返回TRUE
  • 不退货FALSE
  • 取消退货NA
9赞 András Aszódi 9/9/2021 #4

“不等待输入”的原因是,根据手册():readline?readline

在非交互式使用中,结果就好像响应是 RETURN 和 值为 “”。

您偶然发现了 R 的一个“令人惊讶”的功能。

<rant>为什么只在“交互模式”下工作对我来说是一个完全的谜,因为从脚本中请求用户输入是一个完全可以接受的用例。例如,Python 为您提供了可以在需要时调用的函数。readline()input(prompt)</rant>

解决这种混乱的一个相对方便的方法是定义一个函数(“每个编程问题都可以通过另一个间接层次来解决”......

user.input <- function(prompt) {
  if (interactive()) {
    return(readline(prompt))
  } else {
    cat(prompt)
    return(readLines("stdin", n=1))
  }
}

一个积极的副作用是,您可以在 中添加各种不错的输入验证。但我怀疑这是否是 .user.input()readline()

0赞 NiallMcS 6/15/2022 #5

使用 svDialogs 可以让你做到这一点。

它并不完全使用 readline,但确实实现了与您正在寻找的结果类似的结果。

在填充对话框之前,代码不会运行:

library(svDialogs)

raw <- dlgInput("TRUE or FALSE -- this is a validation run: ",Sys.info()["raw"])$res


if (raw == "F" | raw == "FALSE" | raw == "False"){
validation <- F
} else{
  validation <- T
}
rm(raw)

评论

0赞 IRTFM 8/30/2022
该功能的帮助页面目前:“此对话框的'RStudio'版本不允许使用空字符串。因此,为了获得更好的可移植性,尽量不要期望用户出现空字符串(“取消”按钮用于关闭对话框)。在 MacOS 上,单引号和双引号暂时替换为其倾斜版本(分别为 Unicode 字符 u3032 和 u2033),因为触发对话框的命令不允许在字符串中使用引号。常规报价在输出上重置。这是我们发现的唯一有效的黑客。欢迎更好的解决方案!
0赞 Kafei Zhang 8/12/2022 #6

您必须创建一个函数,使用“is.na()”设置一个“if”条件语句,如果输入的值为 null,则再次执行“readline()”。 见下文:

readinteger <- function()
{ 
  n <- readline(prompt="Enter an integer: ")
  n <- as.integer(n)
  if (is.na(n)){
    n <- readinteger()
  }
  return(n)
}
print(readinteger())
rm(list=ls())