#r #dplyr #match #percentage
#r #dplyr #совпадение #процент
Вопрос:
Итак, мой набор данных выглядит следующим образом, а алфавиты являются факторными переменными. Столбцы Pred предназначены для прогнозируемых наблюдений для каждого идентификатора, а реальные столбцы — для реальных наблюдений. Я хочу вычислить общую точность прогнозируемых значений для каждого идентификатора.
ID Pred1 Pred2 Pred3 Real1 Real2 Real3
1 A C E A D B
2 A B D E C C
3 E C A A B D
4 D A B B B D
5 B A C C A B
Итак, я хочу изменить столбец с именем ‘score’, который дает вам процент от числа совпадающих наблюдений между столбцами Pred1, 2, 3 и Real1,2, 3.
Меня интересует только нахождение любых значений ‘Pred’ в любом из ‘реальных’ столбцов.
Если Pred1 найден в одном из Real1, Real2 и Real3, то я даю оценку 1/3.
Если Pred1 И Pred2 (не Pred3) оба найдены в любом из столбцов Real1, Real2 и Real3, (*порядок не имеет значения. Значение Pred1 может быть найдено в Real2 или Real3 — где угодно в ‘Реальных’ столбцах), тогда я даю оценку 2/3.
Я надеюсь, что это имеет смысл. Порядок не имеет значения, и меня интересует только нахождение любого из значений ‘Pred’ в любом из ‘Real’ столбцов.
Итак, я хочу что-то вроде приведенного ниже.
ID Pred1 Pred2 Pred3 Real1 Real2 Real3 Score
1 A C E A D B 1/3
2 A B D E C C 0
3 E C A A B D 1/3
4 D A B B E D 2/3
5 B A C C A B 1
Я пытаюсь написать функцию и попробовал что-то вроде
ifelse(«Pred1″%в% c(«Real1», «Real2», «Real3»), 1/3 ,0 )) но это не сработало должным образом.. (были сообщения об ошибках с приведением к логическому и т.д., Которые я не знал, как решить)
Итак, я тоже пробую разные вещи, но продолжаю застревать с ошибками…
Кто-нибудь может помочь, пожалуйста? Заранее благодарю вас!
Ответ №1:
Это затрудняет сравнение значений с разными уровнями коэффициентов. Сначала мы можем преобразовать столбцы из коэффициентов в символы.
df[-1] <- lapply(df[-1], as.character)
Узнайте индекс прогнозируемого и реального столбцов, а затем для каждой строки проверьте, сколько прогнозируемых наблюдений присутствует в реальных.
pred_cols <- grep("^Pred", names(df))
real_cols <- grep("^Real", names(df))
df$Score <- sapply(1:nrow(df), function(x)
sum(df[x, pred_cols] %in% df[x, real_cols]))/length(pred_cols)
df
# ID Pred1 Pred2 Pred3 Real1 Real2 Real3 Score
#1 1 A C E A D B 0.33
#2 2 A B D E C C 0.00
#3 3 E C A A B D 0.33
#4 4 D A B B B D 0.67
#5 5 B A C C A B 1.00
Поскольку это сравнение по строкам, мы также можем использовать apply
с MARGIN = 1
использованием той же логики. При таком подходе нам не нужно явно преобразовывать столбцы в символы.
apply(df, 1, function(x) sum(x[pred_cols] %in% x[real_cols]))/length(pred_cols)
Ответ №2:
Одной tidyverse
возможностью может быть:
bind_cols(df %>%
gather(var, val, -matches("(Real|ID)")) %>%
select(ID, val), df %>%
gather(var2, val2, -matches("(Pred|ID)")) %>%
select(val2)) %>%
group_by(ID) %>%
summarise(res = paste0(sum(val %in% val2), "/3")) %>%
left_join(df, by = c("ID" = "ID"))
ID res Pred1 Pred2 Pred3 Real1 Real2 Real3
<int> <chr> <fct> <fct> <fct> <fct> <fct> <fct>
1 1 1/3 A C E A D B
2 2 0/3 A B D E C C
3 3 1/3 E C A A B D
4 4 2/3 D A B B B D
5 5 3/3 B A C C A B
Сначала он отдельно преобразует столбцы широкого формата в длинный, который содержит Pred
и Real
. Во-вторых, он объединяет два по столбцам. Наконец, он группирует по «ID», суммирует количество совпадающих наблюдений и объединяет его с исходным df.
Или если количество пар не фиксировано равным 3:
bind_cols(df %>%
gather(var, val, -matches("(Real|ID)")) %>%
select(ID, val), df %>%
gather(var2, val2, -matches("(Pred|ID)")) %>%
select(val2)) %>%
add_count(ID) %>%
group_by(ID) %>%
summarise(res = paste(sum(val %in% val2), first(n), sep = "/")) %>%
left_join(df, by = c("ID" = "ID"))
Или если вы хотите числовую переменную в качестве результата:
bind_cols(df %>%
gather(var, val, -matches("(Real|ID)")) %>%
select(ID, val), df %>%
gather(var2, val2, -matches("(Pred|ID)")) %>%
select(val2)) %>%
add_count(ID) %>%
group_by(ID) %>%
summarise(res = sum(val %in% val2)/first(n)) %>%
left_join(df, by = c("ID" = "ID"))
ID res Pred1 Pred2 Pred3 Real1 Real2 Real3
<int> <dbl> <fct> <fct> <fct> <fct> <fct> <fct>
1 1 0.333 A C E A D B
2 2 0 A B D E C C
3 3 0.333 E C A A B D
4 4 0.667 D A B B B D
5 5 1 B A C C A B