2014-02-11 35 views
0

我試圖測試歐拉的素性測試的準確性。我寫了一個函數euler(),它接受一個數字並測試所有數字的素數,直到輸入並將它們輸出到包含非引數的控制檯。這是它看起來如何:把一個函數的輸出放入一個數據框或一個列表或一個向量R

euler(10) 
[1] 1 
[1] 2 
[1] 3 
[1] "Not prime:" "4"   
[1] 5 
[1] "Not prime:" "6"   
[1] 7 
[1] "Not prime:" "8"   
[1] "Not prime:" "9"   
[1] "Not prime:" "10"   
> 

我想要把這個輸出並把它放到一個數據框架或一個因素或列表。我試過x<-euler(10),但沒有奏效。我只是得到一個NULL向量。這裏是我的歐拉函數的代碼:我試圖定義外的「for」循環,然後使用rbind()數據幀

## Euler's primality test 

euler <- function(k) { 
    for(i in 1:k) { 
    a <- 2; 
    if((a^i-a) %% i == 0) { 
     print(i) 
    } else{print(c("Not prime:",i))} 
    } 
} 

,但我不知道該怎麼做時,有一個if語句。任何幫助讚賞。如果我不清楚,請告訴我,我會進行必要的修改。

+0

該功能執行不力。它應該**返回結果,而不是直接打印。你*可以捕獲這個輸出,但這不是合適的解決方案。適當的解決方案是重寫'euler'來不打印結果(這是忽略該函數也包含語義錯誤:這不*是歐拉的素性測試的適當實現)。 –

+0

@KonradRudolph是的我知道它不是。這裏的重點是讓我學習如何獲取輸出並將其放入數據框中。順便問一下,你是否知道討論歐拉原理性測試的好論文,或者至少與解釋有關?對不起,這些請求。 – Koba

+1

有關說明,[維基百科文章](https://en.wikipedia.org/wiki/Solovay%E2%80%93Strassen_primality_test)其實並不差。 –

回答

3

建議函數返回一些內容而不是打印它。 (如果這是你想要的,你可以在調用函數後自由打印輸出。)

還建議函數的輸出是一致的,例如,在一種情況下不返回一個數字,或者在另一個情況下返回一個字符串「Not prime」。在這裏,返回一個布爾值(對於素數是否爲真)是最有意義的。

也建議(有益)儘可能地向量化函數。所以你可以使用像1:10這樣的向量來調用函數,它會很快返回一個十個布爾值的向量。

is.euler.prime <- function(k) (2^k-2) %% k == 0 

然後,你可以做這樣的事情:

考慮所有的考慮,如下我定義函數

is.euler.prime(10) 
is.euler.prime(1:10) 
which(is.euler.prime(1:10)) 
data.frame(x = 1:10, euler.prime = is.euler.prime(1:10)) 
+0

看起來像我被downvoted,也許是一個很好的理由。我會很感激建設性的反饋。 – flodel

+0

很酷。謝謝。我不認爲有人低估了你。 – Koba

2
euler <- function(k) { 
    L <- c() 
    for(i in 1:k) { 
    a <- 2; 
    if((a^i-a) %% i == 0) { 
     L <- c(L,i) 
    } 
    else{ 
     L <- c(L,paste("Not prime:",i)) 
    } 
    } 
    return(L) 
} 
+0

我不打算評論,但既然這被接受爲答案,讓我們指出1)增長一個向量是非常低效的,所以這將不適用於'k'的大值,2)輸出類型不一致,例如比較'class(euler(3))'和'class(euler(4))',3)使用'for'循環不是很好,也不是高效的,當你可以很容易地進行矢量化時4)這個答案甚至沒有解釋去代碼... – flodel

1

事項有關的「適當性」的功能分開後,您可以使用capture.output捕獲功能的打印輸出。

你的情況:

data<-capture.output(euler(10)) 

這會給你:

[1] "[1] 1"        "[1] 2"        "[1] 3"        "[1] \"Not prime:\" \"4\"   " 
[5] "[1] 5"        "[1] \"Not prime:\" \"6\"   " "[1] 7"        "[1] \"Not prime:\" \"8\"   " 
[9] "[1] \"Not prime:\" \"9\"   " "[1] \"Not prime:\" \"10\"  " 

如果你願意,你可以用貓打印在一個漂亮的方式:

cat(data,sep="\n") 

那會給你回來的結果:

[1] 1 
[1] 2 
[1] 3 
[1] "Not prime:" "4"   
[1] 5 
[1] "Not prime:" "6"   
[1] 7 
[1] "Not prime:" "8"   
[1] "Not prime:" "9"   
[1] "Not prime:" "10" 

如果你想保存結果,而不換行和[1]的,你可以使用gsub清理數據:

data<- gsub("\\[1\\]\\s|[[:punct:]]|\\s*$", "", capture.output(euler(10))) 

這會給你一個載體‘乾淨’的角色字符串是這樣的:

data 
[1] "1"   "2"   "3"   "Not prime 4" "5"   "Not prime 6" "7"   "Not prime 8" "Not prime 9" "Not prime 10" 

但我回答對你想學習如何捕獲打印輸出,這歐拉函數是一個玩具函數來測試的假設。

如果這不是你的意圖(現在我再次閱讀你的評論,我認爲它不是),你應該重新考慮你的功能,並仔細閱讀@ flodel的答案。

+0

酷的方法。這是一個玩具功能。我試圖學習捕獲輸出,所以我可以分析它。 – Koba

相關問題