我有一个数组:
a <- c(1,2,3,4,5)
我想做的事情如下:
b <- roll(a,2) # 4,5,1,2,3
R中是否有类似的功能?我一直在谷歌搜索,但“R Roll”主要给我一些关于西班牙语发音的页面。
答案 0 :(得分:18)
如何使用head
和tail
...
roll <- function( x , n ){
if( n == 0 )
return( x )
c( tail(x,n) , head(x,-n) )
}
roll(1:5,2)
#[1] 4 5 1 2 3
# For the situation where you supply 0 [ this would be kinda silly! :) ]
roll(1:5,0)
#[1] 1 2 3 4 5
使用head
和tail
的一个很酷的事情......你会得到一个负面n
的反向滚动,例如
roll(1:5,-2)
[1] 3 4 5 1 2
答案 1 :(得分:16)
这是一种替代方案,即使x
被“滚动”超过一个完整周期(即abs(n) > length(x)
时),也具有工作优势:
roll <- function(x, n) {
x[(seq_along(x) - (n+1)) %% length(x) + 1]
}
roll(1:5, 2)
# [1] 4 5 1 2 3
roll(1:5, 0)
# [1] 1 2 3 4 5
roll(1:5, 11)
# [1] 5 1 2 3 4
FWIW(而不是它值得多)它也适用于data.frame
s:
head(mtcars, 1)
# mpg cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 21 6 160 110 3.9 2.62 16.46 0 1 4 4
head(roll(mtcars, 2), 1)
# gear carb mpg cyl disp hp drat wt qsec vs am
# Mazda RX4 4 4 21 6 160 110 3.9 2.62 16.46 0 1
答案 2 :(得分:2)
包 binhf 具有 shift 功能:
library(binhf)
shift(1:5, places = 2, dir = "right")
#[1] 4 5 1 2 3
答案 3 :(得分:1)
rearrr
还包含用于向量的 roll_elements_vec()
和用于数据框中一列或多列的 roll_elements()
。
roll_elements()
可以处理分组数据帧,并且可以根据具有给定函数(例如 n
或 rearrr::median_index()
)的组成员找到 rearrr::quantile_index()
设置。
将向量向左滚动 -2 个位置(即向右 2 个位置):
library(rearrr)
library(dplyr)
# Roll vector
roll_elements_vec(1:10, n = -2)
> 9 10 1 2 3 4 5 6 7 8
将数据框中的列向上滚动 -2 个位置:
# Set seed
set.seed(1)
# Create a data frame
df <- data.frame(
"x" = 1:10,
"y" = runif(10) * 10,
"g" = rep(1:2, each = 5)
)
# Roll `x` column
roll_elements(df, cols = "x", n = -2)
> # A tibble: 10 x 4
> y g x .n
> <dbl> <int> <int> <list>
> 1 2.66 1 9 <dbl [1]>
> 2 3.72 1 10 <dbl [1]>
> 3 5.73 1 1 <dbl [1]>
> 4 9.08 1 2 <dbl [1]>
> 5 2.02 1 3 <dbl [1]>
> 6 8.98 2 4 <dbl [1]>
> 7 9.45 2 5 <dbl [1]>
> 8 6.61 2 6 <dbl [1]>
> 9 6.29 2 7 <dbl [1]>
> 10 0.618 2 8 <dbl [1]>
.n
列包含应用的 n
设置。这在使用函数查找 n
时非常有用。
在 x
中的每个组内滚动 g
列:
# Group by `g` and roll `x` within both groups
df %>%
dplyr::group_by(g) %>%
roll_elements(cols = "x", n = -2)
> # A tibble: 10 x 4
> y g x .n
> <dbl> <int> <int> <list>
> 1 2.66 1 4 <dbl [1]>
> 2 3.72 1 5 <dbl [1]>
> 3 5.73 1 1 <dbl [1]>
> 4 9.08 1 2 <dbl [1]>
> 5 2.02 1 3 <dbl [1]>
> 6 8.98 2 9 <dbl [1]>
> 7 9.45 2 10 <dbl [1]>
> 8 6.61 2 6 <dbl [1]>
> 9 6.29 2 7 <dbl [1]>
> 10 0.618 2 8 <dbl [1]>
如果我们不指定一列或多列,则整个数据框都会滚动。如前所述,我们可以通过函数找到 n
,因此这里我们将按中值索引滚动(索引为 1:10,因此中值 = 5.5 并向上舍入到 6 个位置)。
# Roll entire data frame
# Find `n` with the `median_index()` function
roll_elements(df, n_fn = median_index)
> # A tibble: 10 x 4
> x y g .n
> <int> <dbl> <int> <list>
> 1 7 9.45 2 <dbl [1]>
> 2 8 6.61 2 <dbl [1]>
> 3 9 6.29 2 <dbl [1]>
> 4 10 0.618 2 <dbl [1]>
> 5 1 2.66 1 <dbl [1]>
> 6 2 3.72 1 <dbl [1]>
> 7 3 5.73 1 <dbl [1]>
> 8 4 9.08 1 <dbl [1]>
> 9 5 2.02 1 <dbl [1]>
> 10 6 8.98 2 <dbl [1]>
免责声明:我是 rearrr
的作者。它还包含一个 roll_values()
函数,用于滚动元素的值而不是它们的位置。
答案 4 :(得分:0)
您还可以使用permute
软件包:
require(permute)
a <- c(1,2,3,4,5)
shuffleSeries(a, start = 2)
输出:
[1] 3 4 5 1 2
答案 5 :(得分:0)
numpy roll
方法支持向前和向后两个方向,并且接受大于向量长度的移位参数。例如:
Python
import numpy
x=numpy.arange(1,6)
numpy.roll(x,-11)
我们得到:
array([2, 3, 4, 5, 1])
或
x=numpy.arange(1,6)
numpy.roll(x,12)
我们得到:
array([4, 5, 1, 2, 3])
我们可以构建一个 R 函数,该函数考虑了 shift 参数大于向量长度的情况。例如:
R
custom_roll <- function( x , n ){
if( n == 0 | n%%length(x)==0) {
return(x)
}
else if (abs(n)>length(x)) {
new_n<- (abs(n)%%length(x))*sign(n)
return(c( tail(x,new_n) , head(x,-new_n) ))
}
else {
return(c( tail(x,n) , head(x,-n) ))
}
}
让我们看看我们得到了什么,但再次考虑向量 (1,2,3,4,5)。
x<-c(1,2,3,4,5)
custom_roll(x,-11)
我们得到:
[1] 2 3 4 5 1
或
x<-c(1,2,3,4,5)
custom_roll(x,12)
我们得到:
[1] 4 5 1 2 3