在R中移动数据帧

时间:2022-02-07 22:55:22

i have a data frame like this

我有这样的数据框

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

what i want to do is to create a function that shift this data frame by a value. for example:

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

if the value of shifting is 1 the data frame will become:

如果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

etc...

等等...

the function should be like this.

功能应该是这样的。

shift<-function(dataframe,shiftvalue)

is there any simple way to do this in R without entering in a lot of loops??

是否有任何简单的方法在R中执行此操作而不进入很多循环?

4 个解决方案

#1


14  

You can do it many ways, but one way is to use head and tail:

你可以做很多事,但一种方法是使用头部和尾部:

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

#2


10  

I prefer plain old modulo ;-)

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

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

It is pretty straightforward, the only quirk is R's from-one indexing. Also it works for offsets like 0, -7 or 7*nrow(df)...

它非常简单,唯一的怪癖是R的一个索引。它也适用于0,-7或7 * nrow(df)等偏移...

#3


8  

here is my implementation:

这是我的实施:

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

Updated:

更新:

> 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

#4


1  

There's a shift function in taRifx that works on vectors. Applying it results in coersion of all columns to character if any are character, so we'll use a trick from plyr. I'll likely write a data.frame method for it soon:

taRifx中有一个适用于矢量的移位函数。如果有任何字符,应用它会导致所有列的字符变为字符,因此我们将使用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

The advantage of shift is that it takes a bunch of options:

转变的优势在于需要一系列选择:

  • n can be positive or negative to wrap from left/right
  • n可以是正数或负数来从左/右包裹
  • wrap can be turned on or off
  • 可以打开或关闭换行
  • If wrap is turned off, pad can be turned on to pad with NAs so vector remains the same length
  • 如果关闭换行,可以打开垫以使用NA填充,因此向量保持相同的长度

#1


14  

You can do it many ways, but one way is to use head and tail:

你可以做很多事,但一种方法是使用头部和尾部:

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

#2


10  

I prefer plain old modulo ;-)

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

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

It is pretty straightforward, the only quirk is R's from-one indexing. Also it works for offsets like 0, -7 or 7*nrow(df)...

它非常简单,唯一的怪癖是R的一个索引。它也适用于0,-7或7 * nrow(df)等偏移...

#3


8  

here is my implementation:

这是我的实施:

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

Updated:

更新:

> 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

#4


1  

There's a shift function in taRifx that works on vectors. Applying it results in coersion of all columns to character if any are character, so we'll use a trick from plyr. I'll likely write a data.frame method for it soon:

taRifx中有一个适用于矢量的移位函数。如果有任何字符,应用它会导致所有列的字符变为字符,因此我们将使用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

The advantage of shift is that it takes a bunch of options:

转变的优势在于需要一系列选择:

  • n can be positive or negative to wrap from left/right
  • n可以是正数或负数来从左/右包裹
  • wrap can be turned on or off
  • 可以打开或关闭换行
  • If wrap is turned off, pad can be turned on to pad with NAs so vector remains the same length
  • 如果关闭换行,可以打开垫以使用NA填充,因此向量保持相同的长度