Улучшить оператор if else

У меня есть следующая функция в R. Она работает нормально, однако я думаю, что это лучший способ запустить эту функцию.

values <- c("a","b")


print <- function(values){
  
  size <- length(values)

  if (size == 1) {
  
  final <- values[1]
  
}else if (size == 2){
  
  final <- paste0(values[2], " and ", values[1])
}else if (size == 3){
  
  final <- paste0(values[3], " and ",values[2], " and ", values[1])
  
}
  return(final)
}
print(values)

Пользователь может изменить размер значений, поэтому, если он выберет values <- c("a","b", "c"), функция будет работать в последнем условии. Однако последнее условие в искусстве равно второму условному плюс нечто новое. Можно сделать оператор if или что-то в этих строках, использующее предыдущее условие. Что-то вроде:

values <- c("a","b", "c")


print <- function(values){
  
  size <- length(values)

  if (size == 1) {
  
  final <- values[1]
  
}else if (size == 2){
  
  final <- paste0(values[2], " and ", final )
}else if (size == 3){
  
  final <- paste0(values[3], " and ",final )
  
}
  return(final)
}
print(values)

Я думаю, вы спрашиваете о рекурсивных функциях. проверьте это, может быть, это поможет рекурсивные функции в r

G. Can 06.05.2022 15:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
35
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Попробуйте это, которое меняет порядок входного вектора и вставляет «и» между:

newfun <- function(x){
  ifelse(length(x)>1, paste(rev(x), collapse = " and "), x)
}

Выход:

newfun(letters[1])
 # [1] "a"

newfun(letters[1:2])]
 # [1] "b and a"

# and so on...

newfun(letters[1:5])
 # [1] "e and d and c and b and a"

Тестирование этого против вашей функции, чтобы увидеть, идентично ли оно:

all.equal(print(letters[1:3]), 
          newfun(letters[1:3]))
# [1] TRUE

Я также хотел бы сильно предостеречь от именования пользовательских функций, которые уже присущи R (т. е. print() уже является функцией в R.

Спасибо, я попробую это. Настоящее имя совсем не такое, но спасибо за совет.

João Resende 06.05.2022 15:16

Другой способ изменить порядок векторов:

reverse_print <- function(values) paste(values[order(values, decreasing = TRUE)], collapse = " and ")

reverse_print(c("a", "b"))
#[1] "b and a"

reverse_print(c("a", "b", "c", "d"))
#[1] "d and c and b and a"

Однако, если вашей основной целью является создание функции, которая рекурсивно использует условие и предыдущие условия, одним из способов ее достижения является создание прямой рекурсивной функции, в которой функция вызывает себя (см. комментарий @G.Chan для справки ). К сожалению, мне не удалось создать такую ​​функцию для вашего случая. Error: C stack usage 15927520 is too close to the limit было произведено. Такого рода ошибки относительно распространены в рекурсивных функциях, как обсуждалось здесь.

Вместо создания прямой рекурсивной функции я бы предложил использовать while вместе с увеличенным индексом следующим образом:

revprint <- function(values) {
  size   <- length(values)
  if (size == 1) {
    cat(values[1])
  } else {
    while (size > 1) {
      final    <- values[size]
      appended <- paste0(final, " and ")
      size     <- size - 1
      output   <- cat(appended)
    }
    cat(output, values[1], sep = "")
  }
}

revprint("a")
# a

revprint(c("a", "b", "c", "d"))
# d and c and b and a

Если длина ввода (вектор символов) больше 1, эта функция отображает последний символ ввода с помощью paste0, а затем постепенно уменьшает длину ввода. На каждом шаге приращения отображается последний символ нового (более короткого) ввода, к которому добавляется последний символ предыдущего (более длинного) ввода.

Поскольку эта функция использует cat, результат отображается на консоли, но его нельзя напрямую назначить объекту. Чтобы назначить его объекту, вы можете использовать capture.output()

out <- capture.output(revprint(c("a", "b", "c", "d")))
out
#[1] "d and c and b and a"

Другие вопросы по теме