написание функции R с оператором if, который опирается на несколько столбцов информационного кадра - PullRequest
0 голосов
/ 22 февраля 2020

Я пытаюсь написать функцию R, которая состоит из оператора if, где, когда условие в столбце A истинно, оно вычисляет значение в столбце B, в противном случае оно просто возвращает значение из столбца B. I Я уверен, что это легко сделать, и я просто скучаю по чему-то основному c, но я изо всех сил. Есть ли хороший способ сделать это?

Вот пример того, что я пытался

example_df <- data.frame(
  type = c("oranges", "apples", "oranges", "oranges", "apples"),
  sold = c(6, 7, 1, 4, 1)
)

multiply_oranges <- function(x) { if (x$type == "oranges") {
    x$sold * 10
  } else {
    x$sold
  }
}
lapply(example_df, multiply_oranges)

Но это дает мне

Error: $ operator is invalid for atomic vectors

, и у меня возникают проблемы понимание того, что это значит / как это исправить.

Любая помощь в исправлении этой функции или демонстрации лучшего способа сделать это была бы очень признательна. Спасибо!

Ответы [ 2 ]

2 голосов
/ 22 февраля 2020

Интересно, это то, что вы ищете:

library(dplyr)
example_df %>% 
  mutate(Cost=ifelse(type=="oranges", sold*10, sold))
    type sold Cost
1 oranges    6   60
2  apples    7    7
3 oranges    1   10
4 oranges    4   40
5  apples    1    1

Но это кажется большим усилием, особенно если вы хотите добавить больше фруктов. У вас должен быть еще один фрейм данных, содержащий цены на каждый фрукт.

Prices <- data.frame(price=c(10,5), type=c("oranges","apples"))
Prices
  price    type
1    10 oranges
2     5  apples

Затем соедините их вместе и рассчитайте цену net:

library(tidyr)
example_df %>% 
  inner_join(Prices) %>%
  mutate(Net=sold*price)
Joining, by = "type"
     type sold price Net
1 oranges    6    10  60
2  apples    7     5  35
3 oranges    1    10  10
4 oranges    4    10  40
5  apples    1     5   5
2 голосов
/ 22 февраля 2020
  1. lapply не обязательно; это было бы полезно, если у вас есть список кадров (даже один). Вы не Аргумент, что ваша функция задается, - это один столбец за раз. Он «разворачивается» как:

    multiply_oranges(example_df$type)
    multiply_oranges(example_df$sold)
    

    Это не то, что (я думаю) вы намереваетесь.

  2. Ваш if неверен. R if требует , чтобы его условие было длиной 1; если он больше, он предупредит вас с помощью:

    Warning in if (x$type == "oranges") { :
      the condition has length > 1 and only the first element will be used
    

    , который фактически говорит вам, что значение первого значения в $type используется для all в векторе что также (я считаю) не то, что вы намерены. Вместо этого используйте ifelse.

Попробуйте:

multiply_oranges <- function(x) x$sold * ifelse(x$type == "oranges", 10, 1)
multiply_oranges(example_df)
# [1] 60  7 10 40  1

Функция ifelse выполняет условие для каждого элемента в векторе. Если вы посмотрите на ifelse сам по себе, вы увидите

x$type == "oranges"
# [1]  TRUE FALSE  TRUE  TRUE FALSE
ifelse(x$type == "oranges", 10, 1)
# [1] 10  1 10 10  1
x$sold * ifelse(x$type == "oranges", 10, 1)
# [1] 60  7 10 40  1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...