UseR10085
UseR10085

Reputation: 8198

Apply confusionMatrix using pipe operator in R

I want to apply confusionMatrix to a xtabs object using pipe operator. I have used the following code

library(tidyverse)
df %>% 
  xtabs( ~ Observed + Forecasted + Station, data =.) %>% 
  caret::confusionMatrix(.)

This gives me following error

Error in confusionMatrix.table(.) : the table must have two dimensions

I could able to apply it for individual stations like

df %>% subset(Station == "Aizawl") %>% 
  xtabs( ~ Observed + Forecasted, data =.) %>% 
  caret::confusionMatrix(.)

Now how to calculate confusionMatrix for all the stations at a time?

Data

df = structure(list(Station = c("Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", "Aizawl", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", 
"Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip", "Serchhip"
), Observed = c(1, 1, 1, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 
1, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 3, 3, 4, 1, 1, 4, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
4, 4, 4, 3, 4, 1, 1, 1, 1, 1, 3, 5, 5, 5, 3, 1, 1, 3, 1, 1, 1, 
1, 1, 5, 3, 4, 1, 1, 1, 1, 1, 3, 1, 4, 1, 1, 1, 1, 1, 4, 4, 5, 
1, 5, 4, 5, 5, 5, 5, 1, 5, 1, 4, 5, 4, 4, 5, 4, 5, 5, 3, 1, 5, 
3, 4, 3, 4, 5, 5, 5, 5, 4, 4, 5, 4, 4, 5, 5, 5, 5, 4, 5, 5, 5, 
5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 3, 5, 5, 1, 1, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 
3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 3, 
3, 3, 1, 1, 1, 1, 1, 1, 1, 4, 4, 1, 3, 4, 1, 1, 1, 1, 1, 1, 1, 
1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 3, 
6, 5, 5, 4, 1, 5, 1, 1, 1, 1, 4, 5, 5, 5, 5, 5, 5, 1, 1, 4, 1, 
4, 4, 4, 5, 1, 1, 4, 3, 5, 4, 5, 5, 5, 5, 5, 4, 4, 4, 4, 5, 1, 
6, 5, 5), Forecasted = c(1, 1, 1, 5, 5, 1, 1, 1, 5, 5, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 4, 4, 1, 1, 5, 3, 1, 
1, 1, 4, 5, 5, 5, 5, 1, 1, 1, 5, 5, 1, 5, 5, 5, 4, 5, 4, 4, 4, 
3, 4, 4, 1, 1, 5, 5, 4, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 1, 1, 
5, 4, 4, 5, 4, 4, 4, 4, 5, 4, 5, 5, 5, 5, 5, 4, 5, 5, 4, 1, 1, 
4, 4, 5, 5, 5, 5, 1, 4, 5, 5, 1, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 5, 1, 1, 1, 5, 4, 1, 1, 1, 5, 4, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 6, 5, 5, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 5, 5, 4, 1, 1, 1, 1, 1, 4, 1, 1, 1, 4, 4, 4, 4, 1, 4, 1, 3, 
1, 1, 1, 4, 4, 4, 4, 4, 4, 1, 1, 1, 4, 4, 3, 5, 5, 5, 4, 3, 5, 
5, 5, 5, 5, 4, 5, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 1, 4, 4, 
5, 5, 4, 5, 4, 5, 4, 5, 5, 5, 1, 4, 5, 5, 5, 4, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 6)), row.names = c(NA, 333L), class = "data.frame")

Upvotes: 0

Views: 164

Answers (1)

StupidWolf
StupidWolf

Reputation: 46958

If you do it on the whole data.frame, you get a array of tables separated by stations, hence confusionMatrix() complains:

xtabs( ~ Observed + Forecasted + Station, data =df)
, , Station = Aizawl

        Forecasted
Observed  1  3  4  5  6
       1 56  2 13 13  0
       3 12  0  4  8  0
       4  4  0  9 11  0
       5  3  0  7 23  0
       6  0  0  0  0  0

, , Station = Serchhip

        Forecasted
Observed  1  3  4  5  6
       1 76  3 18 18  0
       3  4  0  2  5  0
       4  2  0  4 12  0
       5  1  0  9 10  2
       6  0  0  0  2  0

So you can try using array_tree() with margin = 3 to convert it into a list, with which you can use map() to apply the confusion matrix:

df %>% 
xtabs( ~ Observed + Forecasted + Station, data =.) %>% 
array_tree(.,margin=3) %>% 
map(~caret::confusionMatrix(as.table(.x)))

Upvotes: 1

Related Questions