35

これが私の問題の簡単な例です:

> df <- data.frame(ID=1:10,Score=4*10:1)
> df
       ID Score
    1   1    40
    2   2    36
    3   3    32
    4   4    28
    5   5    24
    6   6    20
    7   7    16
    8   8    12
    9   9     8
    10 10     4
    > diff(df)

Error in r[i1] - r[-length(r):-(length(r) - lag + 1L)] : 
  non-numeric argument to binary operator

このエラーが発生する理由を誰か教えてもらえますか?

4

8 に答える 8

27

おそらく、あなたはこのようなものを探しています:

> tail(df, -1) - head(df, -1)
   ID Score
2   1    -4
3   1    -4
4   1    -4
5   1    -4
6   1    -4
7   1    -4
8   1    -4
9   1    -4
10  1    -4

data.frame2 つの が同じ次元である場合は、それらを減算または加算できます。つまり、ここで行っているのはdata.frame、最初の行が欠落しているtail(df, -1)1 つ ( ) と最後の行が欠落している 1 つ ( head(df, -1)) を減算してそれらを減算することです。

于 2013-04-25T10:18:19.620 に答える
14

dplyr使用する別のオプションmutate_eachは、すべての列をループし、列 ( ) と列 ( ) の差を取得し.、上部の NA 要素を削除するために使用しますlag.na.omit()

library(dplyr)
df %>%
    mutate_each(funs(. - lag(.))) %>%
    na.omit() 

編集:

mutate_each(非推奨 - @PatrickT で言及されているように)代わりに使用mutate_all

df %>%
    mutate_all(funs(. - lag(.))) %>%
    na.omit() 

またはshiftfrom でdata.table。'data.frame' を 'data.table' に変換し ( setDT(df))、列をループします ( lapply(.SD, ..) ) and get the difference between the column (x) and theラグ(シフトby default gives theラグasタイプ = "lag"`)。最初の観測、つまり NA 要素を削除します。

library(data.table)
setDT(df)[, lapply(.SD, function(x) (x- shift(x))[-1])]
于 2016-08-05T08:40:09.437 に答える
5

そのようなことを行うための別の方法を示したいと思いますが、そのような方法でこれを行うことは高く評価されていないと感じることがよくあります.SQLを使用することです.

sqldf(paste("SELECT a.ID,a.Score"
            ,"      , a.Score - (SELECT b.Score"
            ,"                   FROM df b"
            ,"                   WHERE b.ID < a.ID"
            ,"                   ORDER BY b.ID DESC"
            ,"                   ) diff"
            ," FROM df a"
            )
      )

コードは複雑に見えますが、そうではなく、結果でわかるように、いくつかの利点があります。

    ID Score diff
 1   1    40 <NA>
 2   2    36 -4.0
 3   3    32 -4.0
 4   4    28 -4.0
 5   5    24 -4.0
 6   6    20 -4.0
 7   7    16 -4.0
 8   8    12 -4.0
 9   9     8 -4.0
 10 10     4 -4.0

1つの利点は、元のデータフレームを(他のクラスに変換せずに)使用し、データフレームを取得することです(res <- ....に入れます)。もう 1 つの利点は、まだすべての行があることです。そして3つめのメリットは、グループ分けの要因を考えやすいことです。例えば:

df2 <- data.frame(ID=1:10,grp=rep(c("v","w"), each=5),Score=4*10:1)

sqldf(paste("SELECT a.ID,a.grp,a.Score"
            ,"      , a.Score - (SELECT b.Score"
            ,"                   FROM df2 b"
            ,"                   WHERE b.ID < a.ID"
            ,"                         AND a.grp = b.grp"
            ,"                   ORDER BY b.ID DESC"
            ,"                   ) diff"
     ," FROM df2 a"
     )
)


   ID grp Score diff
1   1   v    40 <NA>
2   2   v    36 -4.0
3   3   v    32 -4.0
4   4   v    28 -4.0
5   5   v    24 -4.0
6   6   w    20 <NA>
7   7   w    16 -4.0
8   8   w    12 -4.0
9   9   w     8 -4.0
10 10   w     4 -4.0
于 2015-03-16T17:22:39.763 に答える
5

完全を期すために数年後にこれを追加します [.data.frame-これも達成するために単純なサブセットを使用できます

df[-1, ] - df[-nrow(df), ]
#    ID Score
# 2   1    -4
# 3   1    -4
# 4   1    -4
# 5   1    -4
# 6   1    -4
# 7   1    -4
# 8   1    -4
# 9   1    -4
# 10  1    -4
于 2016-08-05T08:25:30.040 に答える