Я пытаюсь создать функцию, в которой пользователи могут выбирать оператора, который они хотят использовать, что приводит к другому результату. Но я не могу заставить его работать. Я знаю, что мы не можем назначать операторы объекту R, а затем использовать его как оператор на основе имени объекта R. Есть ли способ сделать это? Или, может быть, лучший способ написать функцию?

test <- function(items, operator = "+"){
bank_alpha <- matrix(ncol=6)
colnames(bank_alpha) <- colnames(bank_alpha, do.NULL = FALSE, prefix = "Q")
colnames(bank_alpha)[6] <- "A"
alphabet <- LETTERS[seq(1:26)]

 for (i in 1:items) {
  item <- c(alphabet[i], alphabet[i operator 1], alphabet[i operator  2], alphabet[i operator  3], alphabet[i operator  4], alphabet[i operator 5])
  bank_alpha <- rbind(bank_alpha, item)
  bank_alpha <- na.omit(bank_alpha)
}
return(bank_alpha)
}

  test(items=4, operator = "-") 
6
Sam 4 Сен 2016 в 13:50

3 ответа

Лучший ответ

Посмотрите do.call, который принимает в качестве аргумента имя функции. С участием

operator <- "+"
do.call(operator, list(2,3)

В результате вы получите 5.

В вашем примере:

test <- function(items, operator = "+"){
  bank_alpha <- matrix(ncol=6)
  colnames(bank_alpha) <- colnames(bank_alpha, do.NULL = FALSE, prefix = "Q")
  colnames(bank_alpha)[6] <- "A"
  alphabet <- LETTERS[seq(1:26)]

  for (i in 1:items) {
    item <- c(alphabet[i], alphabet[do.call(operator, list(i,1))], alphabet[do.call(operator, list(i,2))], alphabet[do.call(operator, list(i,3))], alphabet[do.call(operator, list(i,4))], alphabet[do.call(operator, list(i,5))])
    bank_alpha <- rbind(bank_alpha, item)
    bank_alpha <- na.omit(bank_alpha)
  }
  return(bank_alpha)
}

test(items=4, operator = "*") 

Остерегайтесь, "-" в этом случае не имеет смысла.

3
shosaco 4 Сен 2016 в 11:24

Вы можете определить свои собственные операторы в R с помощью знака %, что позволит вам использовать инфиксную нотацию в вашем коде. См. связанный вопрос для получения дополнительных сведений.

test <- function(items, `%op%` = `+`){
    bank_alpha <- matrix(ncol=6)
    colnames(bank_alpha) <- colnames(bank_alpha, do.NULL = FALSE, prefix = "Q")
    colnames(bank_alpha)[6] <- "A"
    alphabet <- LETTERS[seq(1:26)]

    for (i in 1:items) {
       item <- c(alphabet[i], alphabet[i %op% 1], alphabet[i %op% 2], alphabet[i %op% 3], alphabet[i %op% 4], alphabet[i %op% 5])
       bank_alpha <- rbind(bank_alpha, item)
       bank_alpha <- na.omit(bank_alpha)
    }
    return(bank_alpha)
}

test(items=4, `%op%` = `*`)
1
Community 23 Май 2017 в 10:33

Вы можете использовать get() функционально для динамического вызова операторских функций, например:

> get('+')(5, 2)
[1] 7

Функция get() принимает строку в качестве входных данных и возвращает ссылку на функцию, соответствующую этой строке, если она существует.

Обычно операторы вызываются с одним аргументом функции слева и одним справа (например, 5 + 2).

Однако сама операторная функция + принимает в качестве входных данных два аргумента:

> args('+')
function (e1, e2) 
NULL

Вот почему мы можем назвать это так, как мы сделали выше.

4
Keith Hughitt 4 Сен 2016 в 11:18