2011-06-12 18 views
8

tengo una trama de datos como ésteuna trama de datos en I

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 

lo que quiero hacer es crear una función que cambiar esta trama de datos por un valor. por ejemplo:

si el valor de cambio es 1 la trama de datos se convertirá en:

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

la función debe ser así.

shift<-function(dataframe,shiftvalue) 

¿Hay alguna manera simple de hacer esto en R sin entrar en muchos bucles?

Respuesta

14

Usted puede hacer de muchas maneras, pero una forma es utilizar head y 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 
+0

@Prasad Chalasani: me lo puede explicar por favor en detalles – smack

+0

@smack - puede obtener ayuda sobre estas funciones escribiendo '? rbind','? head' y '? tail' en la consola R En resumen, 'head (d, -k)' devuelve * todas menos las últimas filas 'k' * del marco de datos' d'; 'tail (d, k)' devuelve las últimas filas 'k'; 'rbind (d1, d2)' "row-binds" dos marcos de datos 'd1, d2', es decir, crea un marco de datos con' d1' en la parte superior, luego 'd2'. –

8

aquí es mi aplicación:

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

Actualizado:

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

no entendí lo que hiciste, puedes explicarlo por favor, y por cierto no está haciendo el trabajo necesario – smack

+0

@smack no es tan difícil. solo indexando. ver '?" ["' – kohske

10

I prefiera el antiguo módulo simple ;-)

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

Es bastante sencillo, la única peculiaridad es la R de una indexación. También funciona para las compensaciones como 0, -7 o 7*nrow(df) ...

1

Hay una función shift en taRifx que funciona en vectores. Al aplicarlo, se obtiene la cohesión de todas las columnas del personaje, si es que hay personaje, así que usaremos un truco de plyr. probablemente voy a escribir un método para hoja.de.datos pronto:

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 

La ventaja de shift es que se necesita un montón de opciones:

  • n puede ser positivo o negativo para envolver de izquierda a derecha/derecha
  • envoltura se pueden activar o desactivar
  • Si envoltura está apagado, la almohadilla se puede activar a almohadilla con AN tan vector sigue siendo la misma longitud
Cuestiones relacionadas