Tobias
Tobias

Reputation: 3110

Normalize variable per group

Given I have some data, that is grouped twice (once by What and once by Who):

data <-read.table(header = TRUE, text="What  Who    Time
aaa Alice   17
aaa Bob 20
aaa Carol   16
bbb Alice   23
bbb Bob 22
bbb Carol   19
ccc Alice   19
ccc Bob 19
ccc Carol   23
")

How can I normalize one variable (Time here) within a group (eg, what) to one of the other group members (eg Alice of Who)?

  What   Who Time               What   Who Time                What   Who  Time
1  aaa Alice   17             1  aaa Alice   17/17           1  aaa Alice     1
2  aaa   Bob   20             2  aaa   Bob   20/17           2  aaa   Bob 1.176
3  aaa Carol   16       \     3  aaa Carol   16/17      \    3  aaa Carol 0.941
4  bbb Alice   23    ----\    4  bbb Alice   23/23   ----\   4  bbb Alice     1
5  bbb   Bob   22    ----/    5  bbb   Bob   22/23   ----/   5  bbb   Bob 0.957
6  bbb Carol   19       /     6  bbb Carol   19/23      /    6  bbb Carol 0.826
7  ccc Alice   19             7  ccc Alice   19/19           7  ccc Alice     1
8  ccc   Bob   19             8  ccc   Bob   19/19           8  ccc   Bob     1
9  ccc Carol   23             9  ccc Carol   23/19           9  ccc Carol 1.211

Edit: Based on the answer by @amit, I came up with the following function

normalizeTo <- function(df, supergroup, group, val, var, vars=c(var)) {
  data <- df
  indexes <- which(df[[group]] == val)
  norm.factor <- (df[[var]])[indexes]
  names(norm.factor) <- (df[[supergroup]])[indexes]
  for (normvar in vars) {
    data[[paste0(normvar,".norm")]] <- df[[normvar]]/norm.factor[ df[[supergroup]] ]
  }
  data
}

Upvotes: 1

Views: 768

Answers (1)

amit
amit

Reputation: 3462

this would work:

a = which(data$Who=="Alice")
norm.factor = data$Time[a]
names(norm.factor) = data$What[a]
data$norm.time = data$Time/norm.factor[data$What]

Upvotes: 1

Related Questions