【问题标题】:calculate the percentage change of every nth row in the dataframe计算数据框中每第 n 行的百分比变化
【发布时间】:2014-07-30 16:04:23
【问题描述】:

我正在尝试计算数据框值的百分比变化。现在,用户输入了必须计算百分比变化的行。如果用户输入 2,那么将计算每第二行的百分比变化。我有以下功能:

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)
    }

当我测试这个功能时:

change(mtcars[1:5], 1)

我得到以下输出: (仅显示第一行的输出:

                   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

预期输出:

                 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

对于更改 = 2,

预期输出:

                    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

【问题讨论】:

  • 检查 x 和 y 的长度。它应该是不同的。使用print(x); print(y)。在我评论 (#) 一些代码行后,更改(mtcars[1:5],1) [1] 32 [1] 33 [1] 32 [1] 33 [1] 32 [1] 33 [1 ] 32 [1] 33 [1] 32 [1] 33
  • 我试图解决这个问题的另一种方法是:创建一个新的 data.frame 行数 = nrow(DF) 和列数作为结果的列数。 df[,i] &lt;- c(NA,diff(DF[,i]) / head(DF[,i],n-1)) 但这只能在函数中输入 'change' 为 1 时使用。
  • 在注意到您的评论后,我刚刚删除了我的解决方案。如果您将所需的输出发布到 mtcars 的第一列 for change=2 会更好。
  • @akrun,我已经编辑了帖子。我修复了之前的问题。你能看一下吗。谢谢

标签: r


【解决方案1】:

通过运行您的函数change,我得到的输出与您显示的不同。

  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

我想这将有助于获得您的预期输出:

更改=2

  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

更改=3

 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

关于 change=1,您为 mpg 显示的值与行名不匹配。通过改变你的功能:

 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,]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多