У меня есть следующая функция в 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)
Попробуйте это, которое меняет порядок входного вектора и вставляет «и» между:
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.
Спасибо, я попробую это. Настоящее имя совсем не такое, но спасибо за совет.
Другой способ изменить порядок векторов:
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"
Я думаю, вы спрашиваете о рекурсивных функциях. проверьте это, может быть, это поможет рекурсивные функции в r