2014-07-04 20 views
5

在樣式輸出列表「V,W,X,Y和Z」當使用它往往是要以編程方式生成文本的片段,尤其是列出的項目正在使用的情況下, 。例如;簡單的方法中的R

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

將產生

檢查虹膜種爲setosa,雲芝,弗吉尼亞。

正確讀取它應該是

檢查虹膜種爲setosa,花斑癬和弗吉尼亞。

有沒有一種簡單的方法來做到這一點?

+0

也許嘗試檢索您的值,然後使用您當前的格式爲除最後一個值之外的所有值,然後用「和」和列表的最終值連接起來? – ydaetskcoR

+1

是的 - 做這個功能不會太難。你甚至可以有一個oxford.comma參數。這應該顯然默認爲true;) – Dason

+1

爲什麼不使用牛津英文逗號? 「setosa,veriscolor和virginica」暗示雜色和弗吉尼亞都是setosa,這可能不是你想要的 – rawr

回答

9

這是一個pander包中的有用工具

pander::p

p將一個向量中的元素合併到一個字符串中,以實現漂亮的內聯打印。默認參數是從適當的選項值中讀取的(詳見參數說明)。此功能允許你把其產生可變直列,通過纏繞在渦卷提供的字符串向量元素,和分離由主要和結束分隔符(系動詞)元件的表達的結果。如果是雙長度向量,copula中指定的值將用作分隔符。您還可以通過更改限制參數(默認爲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

下面是這樣一個函數

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的示例假)

+2

[pander :: p](https://github.com/Rapporter/pander/blob/master/R/helpers.R#L39:L89) – rawr

+0

@rawr that p函數看起來就像我以後的樣子 - 你能否讓它成爲答案?雖然這很好(+1),但我寧願接受pander :: p - 瞭解pander :: p的存在比一次性解決方案更有價值。 – Corone

4

遞歸函數以不同方式處理的最後兩個元素:

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

試試這個:

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的一般模式應該在這一點上是明確的。

更新添加註意和一些改進。