5

I have the following vector:

v<-c(1,2,3,4,1,2,3,4,2) 

which I want to "transform" into a 3x3 matrix:

matrix <- matrix(data=v,ncol=3)

which I then want to "flip" over (not transpose)

flip_matrix<-matrix[,3:1,drop=FALSE]

It's very easy to use the tidyverse pipe to chain all this but to cut down dependencies I would like to sort this out using base R. I could do it creating several objects and forget about the pipe, but I need to know how this would be done with the base pipe. So far, I had no luck with:

v<-c(1,2,3,4,1,2,3,4,2)

final_matrix <- matrix(data=v,ncol=3) |> .[,3:1.drop=FALSE]()

Which tells me the object "." was not found. I've tried other iterations with no luck... Thanks for your help!

GKi
  • 37,245
  • 2
  • 26
  • 48
Toluene
  • 193
  • 6
  • 3
    Just FYI, the base pipe uses `_` as a placeholder, not `.` like `magrittr`. (But it still doesn't work here, as `_` only works for piping to an argument other than the first argument.) – Gregor Thomas Aug 30 '22 at 15:23
  • Related: https://stackoverflow.com/questions/67799890/column-name-equivalent-for-r-base-pipe – Maël Aug 30 '22 at 16:12
  • Thanks!, yes, I keep confusing . with _ :) – Toluene Aug 30 '22 at 18:10

2 Answers2

8

Another way calling the function [.

v <- c(1,2,3,4,1,2,3,4,2)

matrix(data=v,ncol=3) |> `[`(x=_,,3:1, drop = FALSE)
#     [,1] [,2] [,3]
#[1,]    3    4    1
#[2,]    4    1    2
#[3,]    2    2    3

or without placeholder:

#Does not work as '[' is currently not supported in RHS call of a pipe
#matrix(data=v,ncol=3) |> `[`(,3:1, drop = FALSE)

#But the following will currently work
matrix(data=v,ncol=3) |> base::`[`(,3:1, drop = FALSE)
matrix(data=v,ncol=3) |> (`[`)(,3:1, drop = FALSE)

Or without pipe:

matrix(data=v,ncol=3)[, 3:1, drop = FALSE]
#matrix(v, ncol=3)[, 3:1] #Short alternative
GKi
  • 37,245
  • 2
  • 26
  • 48
  • 2
    I would say that *without pipe* is by far the cleanest. – s_baldur Aug 30 '22 at 16:04
  • We could replace `3` with `sqrt(length(v))` to generalize. – jay.sf Aug 30 '22 at 16:06
  • 1
    @sindri_baldur For me too, but the question was how to use the *pipe*. But I added it to show an alternative. – GKi Aug 30 '22 at 16:09
  • 1
    @jay.sf Only in case we have a square matrix. – GKi Aug 30 '22 at 16:10
  • Well, "3x3" looks like OP is aiming for one ;) – jay.sf Aug 30 '22 at 16:38
  • Thanks all! I definitely have some catch up to do with base R. The non-pipe version is the way to go, but I still need to do things after "flipping it" which involve more piping. Thanks for the sqrt(length(v)). I see you can read my mind!. This is in fact what I´m using in the original code but had to simplify for this example. – Toluene Aug 30 '22 at 18:14
4

We could use a lambda function

matrix(data=v,ncol=3) |>
    {\(x) x[, 3:1, drop = FALSE]}()

-output

      [,1] [,2] [,3]
[1,]    3    4    1
[2,]    4    1    2
[3,]    2    2    3

Or use Alias from magrittr

library(magrittr)
v |> 
  matrix(ncol = 3) |>
  extract(, 3:1)
      [,1] [,2] [,3]
[1,]    3    4    1
[2,]    4    1    2
[3,]    2    2    3
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    Thanks! Trying to avoid magrittr to avoid dependencies (and practice my base R. The first option works nicely! – Toluene Aug 30 '22 at 18:15