William Liu
William Liu

Reputation: 339

SImplify code to group in r

I have a data frame like this:

ID PA   WA  PC
1   2   -6   8 
2   2   -2   7
3   3    7   2
4  -3    3  -6
5   3   20  12
6  15  -17  18
7   3    6  10

I tried to group IDs based on their scores in PA, WA and PC.

I already used this, but it is so cumbersome:

NEW1 <- subset(WA.PC.PA, PA< -5 & WA < -5 & PC> 5, select=c(id, PA, WA, PC))
NEW2 <- subset(WA.PC.PA, PA >5 & WA < -5 & PC< -5, select=c(id, PA, WA, PC))
NEW3 <- subset(WA.PC.PA, PA < -5 & WA >5 & PC< -5, select=c(id, PA, WA, PC))
NEW4 <- subset(WA.PC.PA, PA < -5 & WA < -5 & PC< -5, select=c(id, PA, WA, PC))
NEW5 <- subset(WA.PC.PA, PA > 5 & WA >5 & PC< -5, select=c(id, PA, WA, PC))
NEW6 <- subset(WA.PC.PA, PA >5 & WA < -5 & PC>5, select=c(id, PA, WA, PC))
NEW7 <- subset(WA.PC.PA, PA < -5 & WA >5 & PC>5, select=c(id, PA, WA, PC))
NEW8 <- subset(WA.PC.PA, PA >5 & WA >5 & PC>5, select=c(id, PA, WA, PC))
NEW9 <- subset(WA.PC.PA, PA<5 & PA>-5 & WA<5 & WA>-5 & PC<5 & PC>-5, select=c(id, PA, WA, PC))
NEW10 <- subset(WA.PC.PA, PA < -5 & WA < -5 & PC<5 & PC>-5, select=c(id, PA, WA, PC))
NEW11 <- subset(WA.PC.PA, PA<5 & PA>-5 & WA < -5 & PC<5 & PC>-5, select=c(id, PA, WA, PC))
NEW12 <- subset(WA.PC.PA, PA<5 & PA>-5 & WA<5 & WA>-5 & PC< -5, select=c(id, PA, WA, PC))
NEW13 <- subset(WA.PC.PA, PA< -5 & WA<5 & WA>-5 & PC<5 & PC>-5, select=c(id, PA, WA, PC))
NEW14 <- subset(WA.PC.PA, PA < -5 & WA<5 & WA>-5 & PC< -5, select=c(id, PA, WA, PC))
NEW15 <- subset(WA.PC.PA, PA< -5 & WA<5 & WA>-5 & PC>5, select=c(id, PA, WA, PC))
NEW16 <- subset(WA.PC.PA, PA < -5 & WA >5 & PC<5 & PC>-5, select=c(id, PA, WA, PC))
NEW17 <- subset(WA.PC.PA, PA<5 & PA>-5 & WA < -5 & PC>5, select=c(id, PA, WA, PC))
NEW18 <- subset(WA.PC.PA, PA<5 & PA>-5 & WA<5 & WA>-5 & PC< -5, select=c(id, PA, WA, PC))
NEW19 <- subset(WA.PC.PA, PA<5 & PA>-5 & WA<5 & WA>-5 & PC>5, select=c(id, PA, WA, PC))
NEW20 <- subset(WA.PC.PA, PA<5 & PA>-5 & WA >5 & PC< -5, select=c(id, PA, WA, PC))
NEW21 <- subset(WA.PC.PA, PA<5 & PA>-5 & WA >5 & PC<5 & PC>-5, select=c(id, PA, WA, PC))
NEW22 <- subset(WA.PC.PA, PA<5 & PA>-5 & WA >5 & PC>5, select=c(id, PA, WA, PC))
NEW23 <- subset(WA.PC.PA, PA >5 & WA < -5 & PC<5 & PC>-5, select=c(id, PA, WA, PC))
NEW24 <- subset(WA.PC.PA, PA >5 & WA<5 & WA>-5 & PC< -5, select=c(id, PA, WA, PC))
NEW25 <- subset(WA.PC.PA, PA >5 & WA<5 & WA>-5 & PC<5 & PC>-5, select=c(id, PA, WA, PC))
NEW26 <- subset(WA.PC.PA, PA >5 & WA<5 & WA>-5 & PC>5, select=c(id, PA, WA, PC))
NEW27 <- subset(WA.PC.PA, PA >5 & WA >5 & PC<5 & PC>-5, select=c(id, PA, WA, PC))

As you can see, I group each score into three levels, <-5, between -5~5 and >5. But I want to 1) simplify the code as I need to rewrite the whole thing when I want to assign different number to cutscores of each test.

How can I do that?

Upvotes: 2

Views: 56

Answers (1)

jimmyb
jimmyb

Reputation: 4387

The best way to do this is to use cut followed by interaction then split. Basically, cut will define the partitions of each variable, e.g.,

paCuts = with(WA.PC.PA, cut(PA, c(-Inf, -5, 5, Inf)))
waCuts = with(WA.PC.PA, cut(PA, c(-Inf, -5, 5, Inf)))
levels = interaction(paCuts, waCuts)
split(WA.PC.PA, levels)

The benefit here is that you think about your partitioning as data, i.e., in a vector, versus code; in a conditional statement. It makes changing the various cuts a breeze.

Upvotes: 1

Related Questions