Amanda
Amanda

Reputation: 12737

Why does `cut` object to my labels?

I am trying to label values based on the range they fall into, the way you might with, say, grading assignments. So if I have a data frame of mean quiz scores, and a data frame of number values that I use as the lower cutoff for assigning grades to those means:

grades <- read.table(text="Student Mean
Adam 94
Amanda 85.5
James 81
Noah 72.8333333333333
Zach 57.5", header = TRUE)

letters <- read.table(text = "Letter  Cutoff
A 90
B 80
C 70
D 60
F 0", header = TRUE)

I thought I would be able to use cut to assign a grade to each.

I can use cut to bucket these out, but I'm encountering two exasperating issues:

First, these cutoffs are the minimum, not the maximum and I don't see a way to shift that. And second, cut doesn't want to use the letter grades as labels. If I do this:

cut(grades$Mean, 
    breaks = letters$Cutoff,   
    labels = letters$Letter,
    right = FALSE)

I get an error, lengths of 'breaks' and 'labels' differ. Is it possible to use cut to assign labels to values in this way?

Upvotes: 4

Views: 1730

Answers (1)

Ben Bolker
Ben Bolker

Reputation: 226057

The breaks vector has to be one element longer than the labels vector: you need both a lower and an upper cutoff for each category. Just tack 100 (upper limit) onto the end of the breaks vector (might need to be 100.5 if you have any scores of exactly 100 ...) As pointed out in the comment above, you should have your breaks in ascending order ...

cut(grades$Mean, 
    breaks = c(rev(letters$Cutoff),100),
    labels = rev(letters$Letter),
    right = FALSE)
## [1] A B B C F
## Levels: F D C B A

Upvotes: 6

Related Questions