Lost_in_R
Lost_in_R

Reputation: 11

Rescale Values in percentage in R

I would need your help to rescale values in percentage in R, expressing the values ​​of the same treatment as a percentage of the maximum value.

For example, I have this input

Value Level Treatment
      5     1       A
      7     2       A
      10    4       A
      14    1       B
      20    2       B
      18    4       B
      30    1       C
      30    2       C
      28    4       C

I need this output

     Value Level Treatment
      50     1       A
      70     2       A
      100    4       A
      70     1       B
      100    2       B
      90     4       B
      100    1       C
      100    2       C
      93.3   4       C

I think I can start with

    df <- read.table(header = TRUE, text = '
Value Level Treatment
      50     1       A
      70     2       A
      100    4       A
      70     1       B
      100    2       B
      90     4       B
      100    1       C
      100    2       C
      93.3   4       C
')

    tapply(df$Value, df$Treatment, max)

But, then, I have no idea how to proceed.

Someone would be so kind to help me? I hope this could be useful also for other people.

Thanks a lot.

Upvotes: 0

Views: 722

Answers (3)

akrun
akrun

Reputation: 887068

We can use ave from base R

df1$Value <- with(df1, round(100*Value/ave(Value, Treatment, FUN = max)))
df1$Value
#[1]  50  70 100  70 100  90 100 100  93

Upvotes: 0

Saurabh Chauhan
Saurabh Chauhan

Reputation: 3221

Refer following two one line variant.

You can also use plyr package as shown below:

ddply(df,~Treatment,summarise,Value=Value/max(Value)*100,Level=Level)
            Treatment     Value    Level
     1         A        50.00000     1
     2         A        70.00000     2
     3         A        100.0000     4
     4         B        70.00000     1
     5         B        100.0000     2
     6         B        90.00000     4
     7         C        100.0000     1
     8         C        100.0000     2
     9         C        93.33333     4

Following is the other variant using data.table package:

> dt <- data.table(df)
> dt[,list(Value=Value/max(Value)*100,Level=Level),by=Treatment]
            Treatment     Value    Level
     1         A        50.00000     1
     2         A        70.00000     2
     3         A        100.0000     4
     4         B        70.00000     1
     5         B        100.0000     2
     6         B        90.00000     4
     7         C        100.0000     1
     8         C        100.0000     2
     9         C        93.33333     4

Upvotes: 0

Phil
Phil

Reputation: 4444

Thanks for clarifying. In that case it's easy peasy with dplyr.

Using the following data:

value <- c(5, 7, 10, 14, 20, 18, 30, 30, 28)
level <- c(1, 2, 4)
treatment <- c("A", "A", "A", "B", "B", "B", "C", "C", "C")

df <- data.frame(
  value,
  level,
  treatment,
  stringsAsFactors = FALSE
)

Load tidyverse/dplyr:

library("tidyverse")

Group by treatment group and calculate based on each in turn with:

df <- df %>% 
  group_by(treatment) %>% 
  mutate(value = value / max(value) * 100)

df
## Source: local data frame [9 x 3]
## Groups: treatment [3]
## 
##       value level treatment
##       <dbl> <dbl>     <chr>
## 1  50.00000     1         A
## 2  70.00000     2         A
## 3 100.00000     4         A
## 4  70.00000     1         B
## 5 100.00000     2         B
## 6  90.00000     4         B
## 7 100.00000     1         C
## 8 100.00000     2         C
## 9  93.33333     4         C

Which you can format as you see fit.

Upvotes: 1

Related Questions