Nadeem Hussain
Nadeem Hussain

Reputation: 219

How to assign order to elements in a column in R?

In the following dataset:

Day   Place   Name
 22     X      A
 22     X      A
 22     X      B
 22     X      A
 22     Y      C
 22     Y      C
 22     Y      D
 23     X      B
 23     X      A

How can I assign numbering to the variable Name in following order using R:

Day   Place   Name  Number
 22     X      A     1
 22     X      A     1
 22     X      B     2
 22     X      A     1
 22     Y      C     1
 22     Y      C     1
 22     Y      D     2
 23     X      B     1
 23     X      A     2

In a nutshell, I need to number the names according to their order to occurrence on a certain day and at a certain place.

Upvotes: 5

Views: 1593

Answers (3)

Richie Cotton
Richie Cotton

Reputation: 121177

Use ddply from plyr.

dfr <- read.table(header = TRUE, text = "Day   Place   Name
 22     X      A
 22     X      A
 22     X      B
 22     X      A
 22     Y      C
 22     Y      C
 22     Y      D
 23     X      B
 23     X      A")

library(plyr)
ddply(
  dfr,
  .(Day, Place),
  mutate,
  Number = as.integer(factor(Name, levels = unique(Name)))
)

Or use dplyr, in a variant of beginneR's deleted answer.

library(dplyr)
dfr %>%
  group_by(Day, Place) %>% 
  mutate(Number = as.integer(factor(Name, levels = unique(Name))))

Upvotes: 1

agstudy
agstudy

Reputation: 121618

In base R using tapply:

dat$Number <- 
unlist(tapply(dat$Name,paste(dat$Day,dat$Place),
       FUN=function(x){
         y <- as.character(x)
         as.integer(factor(y,levels=unique(y)))
}))

#    Day Place Name Number
# 1  22     X    A      1
# 2  22     X    A      1
# 3  22     X    B      2
# 4  22     Y    C      1
# 5  22     Y    C      1
# 6  22     Y    D      2
# 7  23     X    B      1
# 8  23     X    A      2

idea

  1. Group by Day and Place using tapply
  2. For each group, create a coerce the Name to the factor conserving the same order of levels.
  3. Coerce the created factor to integer to get the final result.

using data.table(sugar syntax) :

library(data.table)
setDT(dat)[,Number := {
  y <- as.character(Name)
  as.integer(factor(y,levels=unique(y)))
                   },"Day,Place"]

   Day Place Name Number
1:  22     X    A      1
2:  22     X    A      1
3:  22     X    B      2
4:  22     Y    C      1
5:  22     Y    C      1
6:  22     Y    D      2
7:  23     X    B      1
8:  23     X    A      2

Upvotes: 3

flodel
flodel

Reputation: 89097

idx <- function(x) cumsum(c(TRUE, tail(x, -1) != head(x, -1)))
transform(dat, Number = ave(idx(Name), Day, Place, FUN = idx))

#   Day Place Name Number
# 1  22     X    A      1
# 2  22     X    A      1
# 3  22     X    B      2
# 4  22     Y    C      1
# 5  22     Y    C      1
# 6  22     Y    D      2
# 7  23     X    B      1
# 8  23     X    A      2

Upvotes: 1

Related Questions