Swapping subvectors given a vector using R

1

I have a vector column of ¨n¨ components as in the following example:

c(1,3,8,10,23,78,5,15,47,1,8,51)

How can I obtain a vector with R in which a permutation is applied for every six elements?

For example, a possible first permutation with the first six elements is (8,1,78,3,10,23) and another tentative permutation for the following six elements (47,8,15,1,51,5) in this way the final column vector would be c (8,1,7,3,3,10,23,47,8,15,1,51,5). There is in R, some function like SAMPLE that does this routine, or some lines of code for this routine are welcome.

Thank you.

    
asked by Zemitong 14.03.2018 в 19:02
source

2 answers

0

One solution is to carry data frames and use the group_by function of the dplyr package (which in turn comes in tidyverse).

The steps would be mainly to create a partition according to the # of the element and the number of groups, then use the function group_by to group by partition and calculate the new variable (permutacion) using sample.


v <- c(1, 3, 8, 10, 23, 78, 5, 15, 47, 1, 8, 51)
n_para_permutar <- 4

library(tidyverse)

d <- data_frame(v)
d
#> # A tibble: 12 x 1
#>        v
#>    <dbl>
#>  1    1.
#>  2    3.
#>  3    8.
#>  4   10.
#>  5   23.
#>  6   78.
#>  7    5.
#>  8   15.
#>  9   47.
#> 10    1.
#> 11    8.
#> 12   51.

# creamos el numero de fila
d <- mutate(d, fila = row_number())
d
#> # A tibble: 12 x 2
#>        v  fila
#>    <dbl> <int>
#>  1    1.     1
#>  2    3.     2
#>  3    8.     3
#>  4   10.     4
#>  5   23.     5
#>  6   78.     6
#>  7    5.     7
#>  8   15.     8
#>  9   47.     9
#> 10    1.    10
#> 11    8.    11
#> 12   51.    12

# creamos la particion
d <- mutate(d, particion = ceiling(fila/n_para_permutar))
d
#> # A tibble: 12 x 3
#>        v  fila particion
#>    <dbl> <int>     <dbl>
#>  1    1.     1        1.
#>  2    3.     2        1.
#>  3    8.     3        1.
#>  4   10.     4        1.
#>  5   23.     5        2.
#>  6   78.     6        2.
#>  7    5.     7        2.
#>  8   15.     8        2.
#>  9   47.     9        3.
#> 10    1.    10        3.
#> 11    8.    11        3.
#> 12   51.    12        3.

# agrupamos
d <- group_by(d, particion)
d
#> # A tibble: 12 x 3
#> # Groups:   particion [3]
#>        v  fila particion
#>    <dbl> <int>     <dbl>
#>  1    1.     1        1.
#>  2    3.     2        1.
#>  3    8.     3        1.
#>  4   10.     4        1.
#>  5   23.     5        2.
#>  6   78.     6        2.
#>  7    5.     7        2.
#>  8   15.     8        2.
#>  9   47.     9        3.
#> 10    1.    10        3.
#> 11    8.    11        3.
#> 12   51.    12        3.

# creamos los valores de acuerdo a la permutacion
d <- mutate(d, v2 = sample(v))
d
#> # A tibble: 12 x 4
#> # Groups:   particion [3]
#>        v  fila particion    v2
#>    <dbl> <int>     <dbl> <dbl>
#>  1    1.     1        1.   10.
#>  2    3.     2        1.    1.
#>  3    8.     3        1.    3.
#>  4   10.     4        1.    8.
#>  5   23.     5        2.   23.
#>  6   78.     6        2.   15.
#>  7    5.     7        2.    5.
#>  8   15.     8        2.   78.
#>  9   47.     9        3.   47.
#> 10    1.    10        3.   51.
#> 11    8.    11        3.    8.
#> 12   51.    12        3.    1.

# extramos el vector
v2 <- pull(d, v2)
v2
#>  [1] 10  1  3  8 23 15  5 78 47 51  8  1

In summary and in less lines:


v <- c(1,3,8,10,23,78,5,15,47,1,8,51)
n_para_permutar <- 4

library(tidyverse)

data_frame(v) %>%
    mutate(fila = row_number()) %>% # creamos el numero de fila
    mutate(particion =  ceiling(fila/n_para_permutar)) %>% # creamos la particion
    group_by(particion) %>%  # agrupamos
    mutate(v2 = sample(v)) %>% # creamos los valores de acuerdo a la permutacion
    pull(v2)
#>  [1]  8  3 10  1 15 78 23  5  8 51 47  1
    
answered by 14.03.2018 в 22:43
0

You can do it with sample() as you had thought, only that you should do it in two parts, the first for elements 1 to 6 and the second for those from 7 to 12.

mi_vector <- c(1,3,8,10,23,78,5,15,47,1,8,51)
c(sample(mi_vector[1:6]), sample(mi_vector[7:12]))

We do an access operation by vector index using the "brackets" ( [] ) and indicating an element vector, first 1:6 - > c(1,2,3,4,5,6) and then 7:12 - > c(7,8,9,10,11,12) With each of the subvectors we run sample() and finally we concatenate the two subvectors with c()

Now, for a more generic solution, always talking about vectors as input and using the base functionality, we could do the following:

mi_vector <- c(1,3,8,10,23,78,5,15,47,1,8,51)
n <- 6
unlist(lapply(seq(1,length(mi_vector),n),FUN=function(x) {sample(mi_vector[x:(x+n-1)])}))

The logic is the same as explained before, only that we apply it by lapply() dynamically to mi_vector of to groups of n values. It is essential that the vector is a multiple of n .

    
answered by 16.03.2018 в 00:52