How to shift an entire row to right in r and then remove first column?

Viewed 270

Hi I have a tabular data where last row comes one place earlier and generates a new variable X. I want to shift elements of last row by one place right and then delete the first Column(variable X). my data is something like that-

X <- c(NA, NA, NA, NA, NA, "F")
  name <- c("A", "B", "C", "D", "E", 20 )
  var2 <- c(55, 45, 67, 32, 99, 54 )
  var3 <- c(70, 71, 40, 56, 43, 56 )
  var4 <- c(72, 09, 42, 53, 66, 33 )
  var5 <- c(60, 21, 82, 63, 44, NA )
  
  dW_before <- data.frame(X, name, var2, var3, var4, var5)
  

and my Expected outcome is -


  name <- c("A", "B", "C", "D", "E", "F" )
  var2 <- c(55, 45, 67, 32, 99, 20 )
  var3 <- c(70, 71, 40, 56, 43, 54 )
  var4 <- c(72, 09, 42, 53, 66, 56 )
  var5 <- c(60, 21, 82, 63, 44, 33 )
  
  dW_after <- data.frame( name, var2, var3, var4, var5)
  
  

So, In final outcome how can I shift last row to one column right and remove the variable X which became NA for all cells.

Thnanks!

3 Answers

Create an index for the non-NA elements in 'X' column i.e. first column. Use that to index as subset the rows,, while specifying the column index as -1 (to select columns other than the first) and -ncol (to select columns other than the last) in the rhs and lhs of the assignment column indexes

i1 <- !is.na(dW_before$X)
dW_before[i1, -1] <- dW_before[i1, -ncol(dW_before)] 
out <- dW_before[-1]

-ouputt

out
  name var2 var3 var4 var5
1    A   55   70   72   60
2    B   45   71    9   21
3    C   67   40   42   82
4    D   32   56   53   63
5    E   99   43   66   44
6    F   20   54   56   33

This has become a bit verbose but will do the trick to:

library(dplyr)

dW_before %>%
  slice(1:n()-1) %>%
  select(-X) %>%
  bind_rows(dW_before %>% 
              slice_tail() %>% 
              set_names(names(dW_before)[-1]) %>% 
              select(1:length(.)-1) %>%
              mutate(across(!name, as.numeric)))

  name var2 var3 var4 var5
1    A   55   70   72   60
2    B   45   71    9   21
3    C   67   40   42   82
4    D   32   56   53   63
5    E   99   43   66   44
6    F   20   54   56   33

I would have done it like this

library(purrr)

pmap_dfr(dW_before, ~ setNames(na.omit(c(...)), names(dW_before[-1])))
#> # A tibble: 6 x 5
#>   name  var2  var3  var4  var5 
#>   <chr> <chr> <chr> <chr> <chr>
#> 1 A     55    70    72    60   
#> 2 B     45    71    9     21   
#> 3 C     67    40    42    82   
#> 4 D     32    56    53    63   
#> 5 E     99    43    66    44   
#> 6 F     20    54    56    33

Created on 2021-06-19 by the reprex package (v2.0.0)

Related