【问题标题】:How to find the difference in value in every two consecutive rows in R?如何找到R中每两个连续行的值差异?
【发布时间】:2011-12-06 18:08:50
【问题描述】:

我有一个总共 969 行的大表,我需要找出每两行之间的差异,例如row1 和 row2、row2 和 row3、row3 和 row4 等。我该怎么做?命令diff() 告诉我这样做,但我不知道从哪里开始。

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以简单地从包含行 2:n 的第二个数据帧中减去包含原始数据帧的行 1:(n-1) 的数据帧。 (这里n是原始data.frame中的行数):

    # Example data
    df <- data.frame(a=1:4, b=4:1, c=11:14, d=c(2,4,10,0))
    #   a b  c  d
    # 1 1 4 11  2
    # 2 2 3 12  4
    # 3 3 2 13 10
    # 4 4 1 14  0
    
    # Calculate the differences
    diff_df <- df[-1,] - df[-nrow(df),]
    diff_df
    #   a  b c   d
    # 2 1 -1 1   2
    # 3 1 -1 1   6
    # 4 1 -1 1 -10
    

    然后,您可以使用以下方式重命名您认为合适的行:

    row.names(diff_df) <- paste("d", seq_len(nrow(diff_df)), sep="")
    diff_df
    #    a  b c   d
    # d1 1 -1 1   2
    # d2 1 -1 1   6
    # d3 1 -1 1 -10
    

    【讨论】:

    • 你的意思是做同样的事情,但是用行吗?我的意思是,这是相同的想法,但 OP 是在谈论行。​​
    • @joran -- 感谢您的关注!我现在已经修好了。
    • 还可以使用headtail 函数,如tail(df, -1) - head(df, -1)
    【解决方案2】:

    我们也可以使用dplyr::lagdata.table::shift

    library(dplyr)
    df <- mtcars
    
    df %>%  mutate(diff_row = mpg - lag(mpg))
    
    #    mpg cyl  disp  hp drat    wt  qsec vs am gear carb diff_row
    #1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4       NA
    #2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4      0.0
    #3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1      1.8
    #4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1     -1.4
    #5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2     -2.7
    #6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1     -0.6
    #7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4     -3.8
    #....
    

    由于第一行没有lag,默认值为NA。如果我们希望返回的第一个值改为 0,我们可以将默认值设置为变量的 first 值,这样减法就会得到 0。

    df %>%  mutate(diff_row = mpg - lag(mpg, default = first(mpg)))
    
    #    mpg cyl  disp  hp drat    wt  qsec vs am gear carb diff_row
    #1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4      0.0
    #2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4      0.0
    #3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1      1.8
    #4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1     -1.4
    #5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2     -2.7
    #6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1     -0.6
    #7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4     -3.8
    #....
    

    同样的过程也可以使用data.table中的shift来完成,type的默认laglag

    library(data.table)
    setDT(df)[, diff_row := mpg - shift(mpg)]
    

    或者要在第一行获取 0 值,这里我们使用fill 参数。

    setDT(df)[, diff_row := mpg - shift(mpg, fill = first(mpg))]
    

    【讨论】:

      【解决方案3】:

      这是一个如何在内置mtcars data.frame 上使用diff() 的示例。您必须选择一列来执行差异:

      mtcars
                           mpg cyl  disp  hp drat    wt  qsec vs am gear carb
      Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
      Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
      Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
      Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
      [..snip..]
      Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
      Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
      Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
      Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
      

      计算例如的连续差异“qsec”列:

      diff(mtcars$qsec)
       [1]  0.56  1.59  0.83 -2.42  3.20 -4.38  4.16  2.90 -4.60  0.60 -1.50  0.20
      [13]  0.40 -0.02 -0.16 -0.40  2.05 -0.95  1.38  0.11 -3.14  0.43 -1.89  1.64
      [25]  1.85 -2.20  0.20 -2.40  1.00 -0.90  4.00
      

      【讨论】:

      • 这太棒了!如此简单,但如此伟大。有时我觉得 R 是一片广阔的丛林,穿过它的路线很复杂。有简单的路线,但很难找到。这是其中之一。非常感谢!! (它运行得很快,避免了使用 R 进行迭代!!生活没有比这更好的了!
      • 也可以按组执行此操作:stackoverflow.com/questions/14846547/… 这也适用于 Date() 格式的值:stackoverflow.com/questions/30378946/…
      【解决方案4】:

      使用示例数据会更清楚。假设您的意思是“数值差异”,并且您的数据可以表示为矩阵,这样就可以了。

       set.seed(4871)
       m = matrix(sample(1:5,50,TRUE),nrow=10,ncol=5)
       m
       t(apply(m,1,diff))
      

      【讨论】:

        猜你喜欢
        • 2017-06-22
        • 1970-01-01
        • 2022-01-20
        • 1970-01-01
        • 2021-07-24
        • 1970-01-01
        • 1970-01-01
        • 2015-04-06
        • 1970-01-01
        相关资源
        最近更新 更多