【问题标题】:Using colon to specify a sequence in function使用冒号指定函数中的序列
【发布时间】:2014-05-13 05:28:41
【问题描述】:

我大约一周前才开始使用 r。在我的目录中,我有名为 001、002、...010、...331 的 csv 文件。在我下面的部分功能中,要求用户输入 id(例如 1:9)。然后将 id 转换为 001、002、003、...009。但是,如果用户输入 1:10 作为 id,该函数会将 id [10] 输出为“0010”而不是“010”。这会导致我的其余功能失败。关于可能发生的事情有什么建议吗?如果我输入1:10,我想得到001、002、003、004、005、006、007、008、009和010

pollutantmean <- function(directory, pollutant, id) {

    if((id>=1) && (id<10)) {
            fn <- paste("00",id,sep="")
            print(fn)
    } else if((id>=10) && (id<=99)) {
            fn <- paste("0",id,sep="")
            print(fn)
    } else {
            fn <- id
            print(fn)
    }

请我不想为此使用 R 应用功能。我还没走到那一步。

【问题讨论】:

  • 您可以使用sprintf 为自己节省大量时间 - 例如sprintf("%03d",1:10)
  • 我只是用fn &lt;- sprintf("%03d",id) 替换了所有这些,它就像魅力一样。这看起来就像 Java 中的 System.out.printf。但是任何线索为什么我的第一个方法失败了?我无法理解。而且我们还没有在课堂上学习过这种流畅的 sprintf 方法,这表明我的第一种方法可能仍然可以进行一些调整。

标签: r


【解决方案1】:

这会将前导“0”设置为 3 个字符的宽度,并将数值作为字符串。

sprintf("%03s", 1:10)
 [1] "001" "002" "003" "004" "005" "006" "007" "008" "009" "010"

【讨论】:

    【解决方案2】:

    你的函数很接近,但它只评估一个数字id。我添加了一个for 循环来处理一系列数字:

    pollutantmean <- function(idrange) {
      for(id in idrange){
      if((id>=1) && (id<10)) {
        fn <- paste("00",id,sep="")
        print(fn)
      } else if((id>=10) && (id<=99)) {
        fn <- paste("0",id,sep="")
        print(fn)
      } else {
        fn <- id
        print(fn)
      }}
    }
    

    我删除了目录和污染物参数,但它们可以很容易地重新添加。此函数将评估感兴趣范围内的所有数字并将它们打印出来:

    R> pollutantmean(1:10)
    [1] "001"
    [1] "002"
    [1] "003"
    [1] "004"
    [1] "005"
    [1] "006"
    [1] "007"
    [1] "008"
    [1] "009"
    [1] "010"
    R> 
    

    【讨论】:

      【解决方案3】:

      问题在于您使用的是if 语句和短路&amp;&amp; 运算符。在这种情况下,&amp;&amp; 只会查看向量id 的第一个元素并在那里做出决定。在这种情况下 (1&gt;=1) &amp;&amp; (1&lt;10) 所以它执行第一个块。然后你调用fn &lt;- paste("00",id,sep=""),它是矢量化的,因此它对整个id 向量进行操作,因此它将'00'添加到每个元素。您似乎将函数视为存在一些隐式循环,但没有。

      当然@thelastemail 的fn &lt;- sprintf("%03d",id) 建议在这种情况下是正确的,但为了讨论,您的代码可以重写为

      fn <- paste(ifelse(id<10, "00", ifelse(id<100, "0", "")),id,sep="")
      

      因为ifelse 确实有一种隐含循环,它可以为向量中的每个元素做出不同的决定。

      【讨论】:

      • 这也有效。伟大的!您知道如何在不使用 sprintf 的情况下将格式设置为 3 位小数吗? Sprintf 输出一个字符串。我想要一个整数。
      • @sedeh 好吧,首先,整数没有小数位。如果你担心格式化,那么听起来你确实想要一个字符串。否则,010和10有什么区别?输入 sprintf 的值是“数字”值,得到的是格式化的“字符”值。
      猜你喜欢
      • 2018-07-20
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-25
      相关资源
      最近更新 更多