4

I have two columns in the following data frame, and each column has levels according to a specific order:

head(x1)
  soa congruency
1 200          9
2 102          2
3  68          1
4  68          9
5  34          9
6  68          9

head(levels(x1$soa))
[1] "34"  "68"  "102" "200"

head(levels(x1$congruency))
[1] "1" "2" "9

I want to be able to paste the two columns such that the levels of the new variable will be:

"34_1" "34_2" "34_9" "68_1" "68_2" "68_9" etc....

However if I do the following:

x2 <- paste(x1$soa, x1$congruency, sep = "_")

the levels I get are:

x2 <- factor(x2)

class(x2)
[1] "factor"

levels(x2)
[1] "102_1" "102_2" "102_9" "200_1" "200_2" "200_9" "34_1"  "34_2"  "34_9" 
[10] "68_1"  "68_2"  "68_9" 

I know I can change the order of the levels after I paste the columns. However I want to be able to order the columns such that after I paste them I won't need to change the order of the levels. Is there a way in which I can do that? For example I tried to order x1 using the order() function (and I did it correctly), and then paste the two columns but I still get the same order of levels which is not the order I want.

Any help will be greatly appreciated,

Ayala

Henrik
  • 65,555
  • 14
  • 143
  • 159
ayalaall
  • 145
  • 2
  • 16

3 Answers3

10

You can try interaction:

interaction(x1$soa, x1$congruency, sep=  "_", lex.order = TRUE)
## [1] 200_9 102_2 68_1  68_9  34_9  68_9 
## Levels: 34_1 34_2 34_9 68_1 68_2 68_9 102_1 102_2 102_9 200_1 200_2 200_9
David Arenburg
  • 91,361
  • 17
  • 137
  • 196
nicola
  • 24,005
  • 3
  • 35
  • 56
1

You could try:

 library(gtools)
 with(x1, factor(paste(soa, congruency, sep="_"),
     levels=mixedsort(unique(paste(soa, congruency, sep="_")))))
 #[1] 200_9 102_2 68_1  68_9  34_9  68_9 
 #Levels: 34_9 68_1 68_9 102_2 200_9

data

 x1 <- structure(list(soa = structure(c(4L, 3L, 2L, 2L, 1L, 2L), .Label = c("34", 
"68", "102", "200"), class = "factor"), congruency = structure(c(3L, 
2L, 1L, 3L, 3L, 3L), .Label = c("1", "2", "9"), class = "factor")), .Names = c("soa", 
"congruency"), row.names = c("1", "2", "3", "4", "5", "6"), class = "data.frame")
akrun
  • 874,273
  • 37
  • 540
  • 662
0

Still using paste and base functions, you can try :

x2<-paste(x1$soa,x1$congruency,sep="_")`
x2<-factor(x2,levels=paste(rep(levels(x1$soa),e=nlevels(x1$congruency)),levels(x1$congruency),sep="_"))
David Arenburg
  • 91,361
  • 17
  • 137
  • 196
Cath
  • 23,906
  • 5
  • 52
  • 86