Rafa Borges
Rafa Borges

Reputation: 596

Process Blocks of Data in a Dataframe in R

I have a very simple dataframe an its is like this:

id  ts                  val
A   2013-01-01 00:00:00 12
A   2013-01-01 00:00:00 543
B   2013-01-01 00:00:00 76
B   2013-01-01 00:00:00 76
A   2013-01-01 01:00:00 11
C   2013-01-01 01:00:00 42
C   2013-01-01 02:00:00 48

What I want to do is to rescale all values, so they can be between 0 and 1, but grouping by id. In other words, I need to calculate min's and max's for each block of id and then rescale each row by taking its value, subtract from the min group value and divide by min-max. In R form:

function rescale01 <- function(curr, min, max) {return (curr-min/max-min)}

I found a way to get min's and max's from this dataframe, but is too cheesy:

ddply(df[,c(1,3)], "tag", function(x){
    y <- subset(x, select= -tag)
    c(apply(y, 2, min), apply(y, 2, max))
})

Can you suggest a better way to achieve what I need?

Thanks!

Upvotes: 1

Views: 197

Answers (2)

MrFlick
MrFlick

Reputation: 206576

The base function ave() would also work just fine (using @Romain's sample data)

df <- data.frame( id = rep( c(1,2), each = 5 ), x = 1:10 )
df$rescaled <- with(df, ave(x, id, FUN=function(x) {(x-min(x))/(max(x)-min(x))}))
df;

Upvotes: 1

Romain Francois
Romain Francois

Reputation: 17642

Perhaps using dplyr::mutate:

> df <- data.frame( id = rep( c(1,2), each = 5 ), x = 1:10 )
> group_by(df, id) %>% mutate( x = ( x-min(x) ) / ( max(x) - min(x) ) )
Source: local data frame [10 x 2]
Groups: id

   id    x
1   1 0.00
2   1 0.25
3   1 0.50
4   1 0.75
5   1 1.00
6   2 0.00
7   2 0.25
8   2 0.50
9   2 0.75
10  2 1.00

Upvotes: 2

Related Questions