Функция R генерирует неверные результаты - PullRequest
2 голосов
/ 19 января 2020

Я пытаюсь стать лучше с функциями в R, и я работал над функцией, чтобы вытащить каждое нечетное значение от 100 до 500, которое делилось на 3. Я подошел ближе к функции ниже. Он продолжает возвращать все значения правильно, но он также включает первое число в последовательности (101), когда это не должно быть. Любая помощь будет принята с благодарностью. Код, который я написал, выглядит следующим образом:

Test=function(n){
  if(n>100){
   s=seq(from=101,to=n,by=2)
   p=c()
   for(i in seq(from=101,to=n,by=2)){
    if(any(s==i)){
      p=c(p,i)
      s=c(s[(s%%3)==0],i)
     }}
   return (p)}else{
    stop
    }}
  Test(500)

Ответы [ 3 ]

2 голосов
/ 19 января 2020

Вот векторизованная однострочная строка, которая по желанию позволяет изменить нижнюю границу со значения по умолчанию 100 на что угодно. Если границы неправильные, он возвращает пустой вектор, а не выдает ошибку.

Он работает, создавая вектор 1:500 (или, в более общем случае, 1:n), а затем проверяет, больше ли каждый элемент чем 100 (или любую нижнюю границу m, которую вы установили), И является ли каждый элемент нечетным И делится ли каждый элемент на 3. Он использует функцию which для возврата индексов элементов, которые прошли все тесты.

Test <- function(n, m = 100) which(1:n > m & 1:n %% 2 != 0 & 1:n %% 3 == 0)

Таким образом, вы можете использовать его, как указано в вашем вопросе:

Test(500)
# [1] 105 111 117 123 129 135 141 147 153 159 165 171 177 183 189 195 201 207 213 219
# [21] 225 231 237 243 249 255 261 267 273 279 285 291 297 303 309 315 321 327 333 339
# [41] 345 351 357 363 369 375 381 387 393 399 405 411 417 423 429 435 441 447 453 459
# [61] 465 471 477 483 489 495

Или поиграть с верхними и нижними границами:

Test(100, 50)
# [1] 51 57 63 69 75 81 87 93 99
2 голосов
/ 19 января 2020

Вот функция, которая получает все четные, не кратные 3. Она полностью векторизована, без циклов.

  1. Проверьте, находится ли n в пределах диапазона [100, 500].
  2. Создать целочисленный вектор N от 100 до n.
  3. Создайте логический индекс элементов N, которые делятся на 3, но не на 2.
  4. Извлеките элементы N, которые соответствуют индексу i.

Основная работа выполняется в 3 строки кода.

Test <- function(n){
  stopifnot(n >= 100)
  stopifnot(n <= 500)
  N <- seq_len(n)[-(1:99)]
  i <- ((N %% 3) == 0) & ((N %% 2) != 0)
  N[i]
}

Test(500)
1 голос
/ 19 января 2020

Вот пример функции для вашей цели

Test <- function(n) {
  if(n<100 | n> 500) stop("out of range")
  v <- seq(101,n,by = 2)
  na.omit(ifelse(v%%2==1 & v%%3==0,v,NA))
}
  • stop() вызывается, когда ваш n находится вне диапазона [100,500]
  • ifelse() выходы желаемые нечетные значения + NA
  • na.omit отфильтровывают NA и дают окончательные результаты
...