Reputation: 109
I am trying to get a balance value from a df that looks like this
df1
Name Year Ch1 Origin
A 1995 x1 a
A 1996 x2 b
A 1997 x3 a
A 2000 x4 a
B 1997 y1 c
B 1998 y2 c
while Ch1 is numerical. and I want to add an extra col to have this value:
Name Year Ch1 Bil
A 1995 x1
A 1996 x2 %
A 1997 x3 %
A 2000 x4 %
B 1997 y1
B 1998 y2 %
I want "Bil" to be Xi/Xi-1 (value from previous year divided by recent year) IF Xi>=Xi-1
and
-Xi-1/Xi IF Xi<Xi-1
while i is a Year and i-1 is the year before.
I know I can loop this like:
for (i in nrow(df1))
if (df[i,1]==df[i-1,1]) {
if (df[i,3]>df[i-1,3] {
df$Bil<-(df[i,3]/df[i-1,3])
} else df$Bil<-(-df[i-1,3]/df[i,3])
}
Is there a more elegant or quicker way to calculate this? This way I really need to make sure that the dataset is in the right order (going from older to recent years).
Upvotes: 1
Views: 159
Reputation: 24790
We can use lag
from dplyr
.
library(dplyr)
df1 %>%
arrange(Year) %>%
group_by(Name) %>%
mutate(Bil = case_when(Ch1 >= lag(Ch1) ~ Ch1 / lag(Ch1),
Ch1 < lag(Ch1) ~ -lag(Ch1)/Ch1))
Data
df1 <- structure(list(Name = structure(c(1L, 1L, 1L, 1L, 2L, 2L), .Label = c("A",
"B"), class = "factor"), Year = c(1995L, 1996L, 1997L, 2000L,
1997L, 1998L), Ch1 = structure(1:6, .Label = c("x1", "x2", "x3",
"x4", "y1", "y2"), class = "factor"), Origin = structure(c(1L,
2L, 1L, 1L, 3L, 3L), .Label = c("a", "b", "c"), class = "factor")), class = "data.frame", row.names = c(NA,
-6L))
df1<-df1 %>% mutate(Ch1 = round(runif(n=6,100,1000),2))
Upvotes: 1
Reputation: 2753
Here's a data.table
approach using shift
.
library(data.table)
dat <- as.data.table(df1)
dat$value <- rnorm(6, 20, 1) #adding a numeric column
dat1 <- dat[order(Year)][,
Bil := ifelse(test = shift(x = value, n = 1, type = 'lag') > value,
yes = shift(x = value, n = 1, type = 'lag')/value,
no = value/shift(x = value, n = 1, type = 'lag'))]
> dat
Name Year Ch1 Origin value
1: A 1995 x1 a 19.23394
2: A 1996 x2 b 21.16079
3: A 1997 x3 a 20.87078
4: A 2000 x4 a 20.50770
5: B 1997 y1 c 20.39450
6: B 1998 y2 c 20.53281
> dat1
Name Year Ch1 Origin value Bil
1: A 1995 x1 a 19.23394 NA
2: A 1996 x2 b 21.16079 1.100179
3: A 1997 x3 a 20.87078 1.013895
4: B 1997 y1 c 20.39450 1.023353
5: B 1998 y2 c 20.53281 1.006782
6: A 2000 x4 a 20.50770 1.001224
Upvotes: 0