Reputation: 9
I am trying to calculate the percent change in the values of the dataframe. Now the rows for which the percent change has to be calculated is entered by the user. If the user enters 2 then for every 2nd row the percentage change will be calculated. I have the following function:
change <- function(DF, change) {
numCols <- ncol(DF)
for (i in 1: numCols) {
pctChange <-rep(NA,nrow(DF))
x<-DF[,i]
y<-c(DF[(change+1):nrow(DF),i], rep(NA,change))
pctChange <-round((y-x)*100/x,2)
DF$pct<-pctChange
colnames(DF)[ncol(DF)]<-paste(colnames(DF[i]),"pctChangeby",
change,sep = "")
}
return (DF)
}
When i tested this function:
change(mtcars[1:5], 1)
I got the following output: (just showing output for first row:
mpg mpgpctChangeby1
Mazda RX4 22.8 7.02
Mazda RX4 Wag 24.4 -6.56
Datsun 710 22.8 42.11
Hornet 4 Drive 32.4 -6.17
Expected Output:
mpg mpgpctChangeby1
Mazda RX4 22.8 NA
Mazda RX4 Wag 24.4 7.02
Datsun 710 22.8 -6.56
Hornet 4 Drive 32.4 42.11
For change = 2,
Expected Output:
mpg mpgpctChangeby2
Mazda RX4 21.0 NA
Mazda RX4 Wag 21.0 NA
Datsun 710 22.8 8.57
Hornet 4 Drive 21.4 1.90
Hornet Sportabout 18.7 -17.98
Upvotes: 0
Views: 423
Reputation: 887158
By running your function change
, I am getting a different output than the one you showed.
change(mtcars[1],1)[1:4,]
# mpg mpgpctChangeby1
#Mazda RX4 21.0 0.00
#Mazda RX4 Wag 21.0 8.57
#Datsun 710 22.8 -6.14
#Hornet 4 Drive 21.4 -12.62
I guess this would help in getting your expected output:
mtcars1 <- mtcars[,1] #1 column
x <- c(rep(NA,2), mtcars1[-((length(mtcars1)-1):length(mtcars1))])
y <- c(rep(NA,2), mtcars1[-(1:2)])
round(100*(y-x)/x,2)
# [1] NA NA 8.57 1.90 -17.98 -15.42 -23.53 34.81 59.44 -21.31
#[11] -21.93 -14.58 -2.81 -7.32 -39.88 -31.58 41.35 211.54 106.80 4.63
#[21] -29.28 -54.28 -29.30 -14.19 26.32 105.26 35.42 11.36 -39.23 -35.20
#[31] -5.06 8.63
x <- c(rep(NA,3), mtcars1[-((length(mtcars1)-2):length(mtcars1))])
y <- c(rep(NA,3), mtcars1[-(1:3)])
round(100*(y-x)/x,2)
# [1] NA NA NA 1.90 -10.95 -20.61 -33.18 30.48 25.97 34.27
#[11] -27.05 -28.07 -9.90 -14.61 -36.59 -39.88 -3.29 211.54 192.31 130.61
#[21] -33.64 -49.01 -55.16 -38.14 23.87 79.61 95.49 58.33 -42.12 -24.23
#[31] -50.66 35.44
Regarding the change=1, the values you showed for mpg
are not matching with the rownames. By changing your function:
change <- function(DF, change) {
numCols <- ncol(DF)
for (i in 1: numCols) {
pctChange <-rep(NA,nrow(DF))
x<- c(rep(NA, change), DF[-((nrow(DF)-(change-1)):nrow(DF)),i])
y<-c(rep(NA, change), DF[-(seq_len(change)),i])
pctChange <-round((y-x)*100/x,2)
DF$pct<-pctChange
colnames(DF)[ncol(DF)]<-paste(colnames(DF[i]),"pctChangeby",
change,sep = "")
}
return (DF)
}
change(mtcars[1],2)[1:6,]
# mpg mpgpctChangeby2
#Mazda RX4 21.0 NA
#Mazda RX4 Wag 21.0 NA
#Datsun 710 22.8 8.57
#Hornet 4 Drive 21.4 1.90
#Hornet Sportabout 18.7 -17.98
#Valiant 18.1 -15.42
change(mtcars[1],3)[1:6,]
change(mtcars[1],1)[1:6,]
Upvotes: 1