使用mutate将小标题的多个变量传递给函数会产生NA吗?

时间:2019-05-13 08:40:53

标签: r function dplyr tibble

请告知,我具有以下简单功能:

mifflin_equation <- function(gender = "M", 
                             w_kg = 50,
                             h_cm = 180, 
                             age = 40,
                             activity_type = "sedentary") {

  activity_types <- c("sedentary", "light", "moderate", "active")

  if (!(tolower(activity_type) %in% activity_types)) {

    activity_type <- "sedentary"

  }

  activity_trans_table <- tibble(type = activity_types,
                                 activity_coeff = c(1.2, 1.375, 
                                                    1.55, 1.725))

  activity_coeff <- activity_trans_table$activity_coeff[activity_trans_table$type == tolower(activity_type)]

  common_equation <- (10 * w_kg) + (6.25 * h_cm) - (5 * age)

  if (gender == "M") {

    return((common_equation + 5) * activity_coeff)

  } else if (gender == "F") {

    return((common_equation - 161) * activity_coeff)

  }

}

我正在建立一些选择:

age <- seq.int(30,90)
h <- seq.int(150, 200)
w <- seq.int(40, 150)
activity <- c("sedentary", "light", "moderate", "active")
gender <- c("M", "F")

all_options <- expand.grid(age = age, h = h, w = w, activity = activity, gender = gender)

但是当我尝试dplyr :: mutate上面函数的计算字段时,我得到了第一个计算结果以及所有NA:

mifflin_options <- all_options %>%
  dplyr::mutate(mifflin_eq_calories = mifflin_equation(gender = gender, 
                                                       w_kg = w, 
                                                       h_cm = h,
                                                       age = age,
                                                       activity_type = activity))

我知道,如果只是一个变量,我应该使用sapply,但是这里的解决方案是什么?

2 个答案:

答案 0 :(得分:2)

有些选项可以帮助您获得预期的输出结果

library(dplyr)
library(purrr)
temp <- head(all_options)

1)rowwise

temp %>%
  rowwise() %>%
  mutate(mifflin_eq_calories = mifflin_equation(gender = gender, 
                                                   w_kg = w, 
                                                   h_cm = h,
                                                   age = age,
                                                   activity_type = activity))

2)pmap

temp %>% mutate(mifflin_eq_calories = pmap_dbl(
            list(gender, w, h, age, activity), mifflin_equation))

3)基数R mapply

mapply(mifflin_equation, temp$gender, temp$w, temp$h, temp$age, temp$activity)

4)Vectorize您的功能

new_fun <- Vectorize(mifflin_equation)

4a)使用mutate

申请
temp %>%
 mutate(mifflin_eq_calories = new_fun(gender = gender, 
                                      w_kg = w, 
                                      h_cm = h,
                                      age = age,
                                      activity_type = activity))

4b)或直接

new_fun(temp$gender, temp$w, temp$h, temp$age, temp$activity)

5)data.table

library(data.table)
setDT(temp)[, ans:= mifflin_equation(gender, w, h, age, activity),by = 1:nrow(temp)]

答案 1 :(得分:1)

我们可以使用Map中的base R

temp <- head(all_options)
unlist(do.call(Map, c(f = mifflin_equation, temp)))