#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 Да, именно так.