R 不能被几个数整除的整数

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)

我试图打印一个向量,它的整数在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)]
数据
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.call
with
lapply()

编辑:

这里有一种使用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)))))