在R中移动数据帧

时间:2011-06-12 14:14:28

标签: r

我有一个像这样的数据框

A B value
1 1 0.123
2 1 0.213
3 1 0.543
1 2 0.313
2 2 0.123
3 2 0.412

我想要做的是创建一个将数据框移动一个值的函数。例如:

如果shift的值为1,则数据帧将变为:

A B value
3 2 0.412
1 1 0.123
2 1 0.213
3 1 0.543
1 2 0.313
2 2 0.123

等...

该功能应该是这样的。

shift<-function(dataframe,shiftvalue)

有没有简单的方法在R中执行此操作而不进入大量循环?

4 个答案:

答案 0 :(得分:14)

您可以采取多种方式,但一种方法是使用headtail

df <- data.frame(a=1:10, b = 11:20)

shift <- function(d, k) rbind( tail(d,k), head(d,-k), deparse.level = 0 )


> shift(df,3)
    a  b
4   4 14
5   5 15
6   6 16
7   7 17
8   8 18
9   9 19
10 10 20
1   1 11
2   2 12
3   3 13

答案 1 :(得分:11)

我更喜欢普通的旧模数; - )

shift<-function(df,offset) df[((1:nrow(df))-1-offset)%%nrow(df)+1,]

这很简单,唯一的怪癖是R的一个索引。此外,它适用于0-77*nrow(df) ...

等抵消

答案 2 :(得分:8)

这是我的实施:

> shift <- function(df, sv = 1) df[c((sv+1):nrow(df), 1:sv),]
> head(shift(iris, 3))
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa
7          4.6         3.4          1.4         0.3  setosa
8          5.0         3.4          1.5         0.2  setosa
9          4.4         2.9          1.4         0.2  setosa
> tail(shift(iris, 3))
    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
148          6.5         3.0          5.2         2.0 virginica
149          6.2         3.4          5.4         2.3 virginica
150          5.9         3.0          5.1         1.8 virginica
1            5.1         3.5          1.4         0.2    setosa
2            4.9         3.0          1.4         0.2    setosa
3            4.7         3.2          1.3         0.2    setosa
>

更新:

> shift <- function(df, sv = 1) df[c((nrow(df)-sv+1):nrow(df), 1:(nrow(df)-sv)),]
> head(shift(iris, 3))
    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
148          6.5         3.0          5.2         2.0 virginica
149          6.2         3.4          5.4         2.3 virginica
150          5.9         3.0          5.1         1.8 virginica
1            5.1         3.5          1.4         0.2    setosa
2            4.9         3.0          1.4         0.2    setosa
3            4.7         3.2          1.3         0.2    setosa
> tail(shift(iris, 3))
    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
142          6.9         3.1          5.1         2.3 virginica
143          5.8         2.7          5.1         1.9 virginica
144          6.8         3.2          5.9         2.3 virginica
145          6.7         3.3          5.7         2.5 virginica
146          6.7         3.0          5.2         2.3 virginica
147          6.3         2.5          5.0         1.9 virginica

答案 3 :(得分:1)

taRifx中有一个shift函数可用于向量。如果有任何字符,应用它会导致所有列的字符变为字符,因此我们将使用plyr中的技巧。我很快就会为它编写一个data.frame方法:

dd <- data.frame(b = seq(4),
      x = c("A", "D", "A", "C"), y = c('a','b','c','d'),
      z = c(1, 1, 1, 2),stringsAsFactors=FALSE)

> dd
  b x y z
1 1 A a 1
2 2 D b 1
3 3 A c 1
4 4 C d 2

library(taRifx)
library(plyr)
shift.data.frame <- colwise(shift)
> shift.data.frame(dd)
  b x y z
1 2 D b 1
2 3 A c 1
3 4 C d 2
4 1 A a 1
> shift(dd,n=-1)
  b x y z
1 4 C d 2
2 1 A a 1
3 2 D b 1
4 3 A c 1
> shift(dd,n=-1,wrap=FALSE)
  b x y z
1 1 A a 1
2 2 D b 1
3 3 A c 1
> shift(dd,n=-1,wrap=FALSE,pad=TRUE)
   b    x    y  z
1 NA <NA> <NA> NA
2  1    A    a  1
3  2    D    b  1
4  3    A    c  1

shift的优势在于它需要一系列选项:

  • n可以是正面还是负面以从左/右包裹
  • 包裹可以打开或关闭
  • 如果关闭包裹,可以打开打击垫以使用NA填充,因此矢量保持相同的长度