【问题标题】:Simple way to output list in the style "V, W, X, Y, and Z" in R在R中以“V,W,X,Y和Z”样式输出列表的简单方法
【发布时间】:2014-08-26 04:50:45
【问题描述】:

在使用rmarkdown 时,您经常希望以编程方式生成文本片段,特别是列出正在使用的项目。例如;

The species of iris examined were `r cat(as.character(unique(iris$Species)), sep = ", ")`.

这会产生

检查的虹膜种类是 setosa、versicolor、virginica。

要正确阅读应该是

检查的鸢尾花种类是 setosa、versicolor 和 virginica。

有没有简单的方法来做到这一点?

【问题讨论】:

  • 也许尝试事先检索您的值,然后对除最后一个值之外的所有值使用当前格式,然后将其与“and”和列表的最终值连接起来?
  • 是的 - 制作一个函数来做到这一点不会太难。你甚至可以有一个 oxford.comma 参数。这显然应该默认为 true ;)
  • 为什么不用牛津逗号? "setosa, veriscolor and virginica" 暗示 versicolor 和 virginica 都是 setosa,这可能不是你想要的
  • 添加了牛津逗号。现在开心? :-)
  • 直到地球和平

标签: string r formatting r-markdown


【解决方案1】:

就是这样一个函数

wordlist<-function(w, oxford=F) {
    if(length(w)==1) return(w);
    if(length(w)==2) return(paste(w[1],"and",w[2]));
    paste0( paste(w[-length(w)], collapse=", "), 
        ifelse(oxford,",","")," and ", w[length(w)] )
}

wordlist(unique(iris$Species))
# [1] "setosa, versicolor and virginica"

(根据 OP 的示例,oxford 设置为 false)

【讨论】:

  • @rawr p 函数看起来正是我所追求的 - 你能回答吗?虽然这很好 (+1),但我更愿意接受 pander::p - 了解 pander::p 的存在比一次性解决方案更有价值。
【解决方案2】:

递归函数以不同方式处理最后两个元素:

wordlist <- function(w) { 
                          if (length(w) <= 2) {
                            paste(w, collapse=' and ') # Or collapse=', and '
                          } else {
                            paste(w[1], Recall(w[-1]), sep=', ')
                          }
                        }
wordlist(LETTERS[1:6])
## [1] "A, B, C, D, E and F"

【讨论】:

    【解决方案3】:

    这是pander 包中的有用工具之一

    pander::p

    p 将向量的元素合并到一个字符串中,以便进行漂亮的内联打印。默认参数是从适当的选项值中读取的(有关详细信息,请参见参数描述)。此函数允许您将产生变量的表达式的结果内联,方法是使用 wrap 中提供的字符串包装向量元素,并通过主分隔符和结束分隔符 (sep 和 copula)。如果是两个长度的向量,copula 中指定的值将用作分隔符。您还可以通过更改 limit 参数中指定的整数值(默认为 Inf)来控制所提供向量的长度。

    示例:

    devtools::install_github('Rapporter/pander')
    ## also available on cran:
    # install.packages('pander')
    
    library(pander)
    
    p(levels(iris$Species), wrap = '')
    # "setosa, versicolor and virginica"
    
    p(levels(iris$Species), wrap = '', copula = ', and ')
    # "setosa, versicolor, and virginica"
    

    【讨论】:

      【解决方案4】:

      试试这个:

      toStringAnd <- function(s) {
          n <- length(s)
          if (n < 2) s else toString(s[-n], paste("and", s[n]))
      }
      
      # test
      toStringAnd( tail(LETTERS) )
      ## [1] "U, V, W, X, Y, and Z"
      

      注意:以上回答了问题,但以防万一您改变主意并决定在and 之前不使用逗号,那么:

      toStringAnd2 <- function(s) {
          n <- length(s)
          if (n < 2) s else paste(toString(s[-n]), "and", s[n])
      }
      
      # test
      toStringAnd2( tail(LETTERS) )
      ## [1] "U, V, W, X, Y and Z"
      

      根据您的需要,可能还有其他变体,例如,如果只有两个输入组件,则不使用逗号;如果有两个以上,则使用逗号,但组合 toStringpaste 的一般模式应该是在这一点上清除。

      更新添加了注释和一些改进。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-25
        • 2017-12-27
        • 1970-01-01
        • 2013-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多