2014-02-11 89 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

相关问题