функция, объявляющая имена столбцов

#r #dataframe #recode

Вопрос:

У меня есть функция, написанная на R. В основном я применяю функцию к столбцу фрейма данных на основе его значений. Кто-нибудь может мне помочь?……………………………

 asd <- data.frame(a = c("High Impact", "High Impact", "Medium Impact"),
                  b = c("High Impact", "No Impact", "High Impact"),
                  c = c("Low Impact", "No Impact", "Medium Impact"))

final_score <- function(q1,q2,q3){
  # ifelse(c == "A", "Low", "High")
  if (q1 == "Not Applicable") {
    q1_value = 0
  } else if (q1 == "No Impact") {
    q1_value = 0
  } else if (q1 == "Low Impact") {
    q1_value = 1
  } else if (q1 == "Medium Impact") {
    q1_value = 2
  } else if (q1 == "High Impact") {
    q1_value = 3
  }
  
  if (q2 == "Not Applicable") {
    q2_value = 0
  } else if (q2 == "No Impact") {
    q2_value = 0
  } else if (q2 == "Low Impact") {
    q2_value = 1
  } else if (q2 == "Medium Impact") {
    q2_value = 2
  } else if (q2 == "High Impact") {
    q2_value = 3
  }
  
  if (q3 == "Not Applicable") {
    q3_value = 0
  } else if (q3 == "No Impact") {
    q3_value = 0
  } else if (q3 == "Low Impact") {
    q3_value = 1
  } else if (q3 == "Medium Impact") {
    q3_value = 2
  } else if (q3 == "High Impact") {
    q3_value = 3
  }
  fs  = q1_value   q2_value   q3_value
  return(fs)
}

###Expected output
asd$new <- final_score(asd$a,asd$b,asd$c)
              a           b             c       new
1   High Impact High Impact    Low Impact       7
2   High Impact   No Impact     No Impact       3
3 Medium Impact High Impact Medium Impact       7
 

У меня есть функция, написанная на R. В основном я применяю функцию к столбцу фрейма данных на основе его значений. Кто-нибудь может мне помочь?……………………………

Ответ №1:

В dplyr вы можете использовать case_when и across

 library(dplyr)

asd %>%
  mutate(new = rowSums(across(.fns = ~case_when(. %in% c("Not Applicable", "No Impact") ~ 0, 
                                  . =="Low Impact" ~ 1, 
                                  . == "Medium Impact" ~ 2, 
                                  . == "High Impact" ~ 3))))

#              a           b             c new
#1   High Impact High Impact    Low Impact   7
#2   High Impact   No Impact     No Impact   3
#3 Medium Impact High Impact Medium Impact   7
 

Комментарии:

1. Я писал точно так же (10 минут спустя). Такой замечательный ответ.

2. Привет, предположим, что есть еще одна колонка под названием «d» . В этом случае, как мы берем только 3 столбца. asd <- data.frame(a = c("Low Impact", "High Impact", "Medium Impact"), b = c("High Impact", "No Impact", "High Impact"), c = c("Low Impact", "No Impact", "Medium Impact"), d = c(1,2,3))

3. В across вы можете сделать across(a:c, ~case_when(.....))

Ответ №2:

Когда вы обнаружите, что копируете свой код снова и снова, подумайте, является ли цикл или функция лучшим ответом. Это предложение выполнить вычисления без дополнительных пакетов. Однако перекодирование может быть выполнено еще проще с помощью подходящих пакетов. recode Функция in car -это всего лишь одно предложение из многих.

 # Your example data
asd <- data.frame(a = c("High Impact", "High Impact", "Medium Impact"),
                  b = c("High Impact", "No Impact", "High Impact"),
                  c = c("Low Impact", "No Impact", "Medium Impact"))


# a small function for one value:
score <- function(value){
  if (value == "Not Applicable") return(0)
  if (value == "No Impact") return(0)
  if (value == "Low Impact") return(1)
  if (value == "Medium Impact") return(2)
  if (value == "High Impact") return(3)
  return(NA)
}

# apply that small function to each value in asd

apply(asd, 1:2, score)

# rowSums are the sums of the rows...

asd$new <- rowSums(apply(asd, 1:2, score))

print(asd)
 

Ответ №3:

Базовый вариант R

 asd$new <- rowSums(
  `dim<-`(
    as.integer(factor(
      as.matrix(asd),
      levels = c("Low Impact", "Medium Impact", "High Impact")
    )),
    dim(asd)
  ),
  na.rm = TRUE
)
 

дает

 > asd
              a           b             c new
1   High Impact High Impact    Low Impact   7
2   High Impact   No Impact     No Impact   3
3 Medium Impact High Impact Medium Impact   7
 

Комментарии:

1. Преобразование в коэффициент и использование числового значения было бы хорошей альтернативой, если бы не две строки («Неприменимо» и «Не влияет»), имеющие одинаковое значение 0.

2. @crestor Да, именно так.