R 不能被几个数整除的整数
我试图打印一个向量,它的整数在1到100之间,在R中不能被2,3和7整除R 不能被几个数整除的整数,r,R,我试图打印一个向量,它的整数在1到100之间,在R中不能被2,3和7整除 我尝试了seq,但我不知道如何继续。我们可以在循环中使用lappy使用模运算,通过求反(!)将0转换为TRUE,使用Reduce和找到相应的列表元素,这些元素要么为TRUE,要么求反,要么将“v1”子集 v1[!Reduce(`|`,lapply(c(2,3,7), function(x) !(v1 %%x)))] 或者,也可以用更快的方式来代替循环 v1[!(!v1%%2) + (!v1%%3) + (!v1%%7)
我尝试了
seq
,但我不知道如何继续。我们可以在循环中使用lappy
使用模运算,通过求反(!
)将0转换为TRUE,使用Reduce
和
找到相应的列表
元素,这些元素要么为TRUE,要么求反,要么将“v1”子集
v1[!Reduce(`|`,lapply(c(2,3,7), function(x) !(v1 %%x)))]
或者,也可以用更快的方式来代替循环
v1[!(!v1%%2) + (!v1%%3) + (!v1%%7)]
数据
v1基本上,您需要计算模2、模3和模7中的每一个数。您可以使用outer
在单个矢量化操作中执行所有模运算,使用rowsumes
识别1:100
中未完全除以2、3或7的元素
v1 <- 1:100
v1[rowSums(outer(v1, c(2, 3, 7), "%%") == 0) == 0]
# [1] 1 5 11 13 17 19 23 25 29 31 37 41 43 47 53 55 59 61 65 67 71 73 79 83 85 89 95 97
v1另一个选项是使用Filter
来过滤序列中符合条件的任何数字:
Filter(function(i) { all(i %% c(2,3,7) != 0) }, seq(100))
## [1] 1 5 11 13 17 19 23 25 29 31 37 41 43 47 53 55 59 61 65 67 71 73 79 83 85 89 95 97
请注意,虽然这可能(IMO)是最可读的,但它的性能最差(到目前为止):
更新了以考虑rawr的循环解决方案:
microbenchmark(
filter={ v1 <- seq(100); Filter(function(i) { all(i %% c(2,3,7) != 0) }, v1) },
reduce={ v1 <- seq(100); v1[!Reduce(`|`,lapply(c(2,3,7), function(x) !(v1 %%x)))] },
rowout={ v1 <- seq(100); v1[rowSums(outer(v1, c(2, 3, 7), "%%") == 0) == 0] },
looopy={ v1 <- seq(100); for (ii in c(2,3,7)) v1 <- v1[-which(v1 %% ii == 0)]; v1 },
times=1000
)
## Unit: microseconds
## expr min lq mean median uq max neval cld
## filter 108.280 118.7000 143.88592 126.2155 136.6290 2349.952 1000 c
## reduce 21.552 23.8095 25.91997 24.8150 25.8580 144.067 1000 ab
## rowout 26.075 28.4920 31.11812 29.5350 31.2125 184.225 1000 b
## looopy 14.149 16.0765 18.11806 16.8995 17.8595 160.485 1000 a
microbenchmark(
filter={v1其他答案更好,但是如果您确实需要使用for
循环,正如建议的那样,这可能是一种可能性:
x <- vector()
n <- 1L
for(i in 1:100){if (i%%2!=0 & i%%3!=0 & i%%7!=0) {x[n] <- i; n <- n+1}}
#> x
# [1] 1 5 11 13 17 19 23 25 29 31 37 41 43 47 53 55 59 61 65 67 71 73 79 83 85 89 95 97
x不必显式使用模运算,我们可以通过倒计时轻松地生成负模序列。然后,对于三个序列中的每一个,我们可以将它们或全部放在一起,然后将其放入which()
如果我们想少一点硬编码,我们可以使用do.callwithlapply()
:
编辑:
这里有一种使用logicals的方法:
v1只是出于好奇:这是家庭作业还是自学?OP在另一个(dup)q中说这是家庭作业。我想“会见”一位认为这是教授R的好方法的老师。这不是一个糟糕的练习。我经常要求学生编写R代码来选择向量的奇数或偶数元素(显然比这更普遍有用,但也没什么不同…)不关注for
(尤其是对研发和编程新手而言)最终会降低他们摸索矢量化操作的速度吗?也许我只是看到了太多for
循环问题(根据定义,这是一个地方,在那里可能会有问题的人去摸索一些东西)。一个简单的循环loop={v1怎么样
x <- vector()
n <- 1L
for(i in 1:100){if (i%%2!=0 & i%%3!=0 & i%%7!=0) {x[n] <- i; n <- n+1}}
#> x
# [1] 1 5 11 13 17 19 23 25 29 31 37 41 43 47 53 55 59 61 65 67 71 73 79 83 85 89 95 97
which(as.logical(pmin(rep_len(1:0, 100),
rep_len(2:0, 100),
rep_len(6:0, 100))))
which(as.logical(do.call(pmin, lapply(c(2,3,7)-1, function(x)rep_len(x:0, 100)))))