Noura
Noura

Reputation: 474

Shift rows values according to a vector

data.tab <- read.table(text = "
0 0 344 34 93 76 190 78 0
0 0 350 16 45 22 21 0 0
0 0 366 11 87 65 71 0 0
0 0 780 28 46 33 30 0 0
0 0 997 55 98 65 12 0 0  
0 0 402 30 11 18 198 0 0")

I want to shift non zero value of rows to the right or to the left according to values this vector :

vect <- c(-2, 1, 0, 2, 2, 2, 2, 2, -2).

The first row will be shifted by two columns to the left to obtain :

344 34 93 76 190 78 0 0 0

The second row will be shifted by one column to the right to obtain:

0 0 0 350 16 45 22 21 0 

In my previous post some one suggested the mutate function of dplyr package which works well, but required a single integer

Upvotes: 0

Views: 397

Answers (1)

AntoniosK
AntoniosK

Reputation: 16121

Here is a tidyverse solution using map2 to apply a shift value to the corresponding row of your dataset:

data.tab <- read.table(text = "
0 0 344 34 93 76 190 78 0
0 0 350 16 45 22 21 0 0
0 0 366 11 87 65 71 0 0
0 0 780 28 46 33 30 0 0
0 0 997 55 98 65 12 0 0  
0 0 402 30 11 18 198 0 0")

library(tidyverse)

# for reproducibility
set.seed(15)

data.tab %>%
  group_by(id = row_number()) %>%    # group by row id
  nest() %>%                         # nest data
  mutate(shift = sample(-2:2, nrow(data.tab), replace=TRUE),  # create and add the shift values for each row             
         d = map2(shift, data, ~if(.x >= 0) lag(.y, .x, default = 0L) else lead(.y, abs(.x), default = 0L))) %>%  # apply shift value to corresponding rows
  unnest(d) %>%                      # unnest shifted data        
  select(-id, -data)                 # remove unnecessary columns


# # A tibble: 6 x 10
#   shift    V1    V2    V3    V4    V5    V6    V7    V8    V9
#   <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
# 1     1     0     0     0   344    34    93    76   190    78
# 2    -2   350    16    45    22    21     0     0     0     0
# 3     2     0     0     0     0   366    11    87    65    71
# 4     1     0     0     0   780    28    46    33    30     0
# 5    -1     0   997    55    98    65    12     0     0     0
# 6     2     0     0     0     0   402    30    11    18   198

The key point it to use lag if the shift value is positive, otherwise use lead and the absolute shit value.

Upvotes: 2

Related Questions