Home > front end >  Why doesn't this pipeline with a lambda function return a matrix?
Why doesn't this pipeline with a lambda function return a matrix?

Time:09-27

Trying to work out how the new base R pipelines and lambda functions work. I want to generate a matrix with three columns and rename the columns. I thought this would work:

mat1 <- matrix(rnorm(24), ncol = 3) |>
     (\(x) colnames(x) <- c("X", "Y", "Z"))()

but it just returns the vector of column names

> mat1
[1] "X" "Y" "Z"

Can anyone explain to me why this doesn't work?

CodePudding user response:

Your code is similar to

mat <- matrix(rnorm(24), ncol = 3)
abc <- colnames(mat) <- c("X", "Y", "Z")
abc
#[1] "X" "Y" "Z"

which returns only the column names and not the matrix.

You need to return the changed matrix value at the end of the pipe

mat1 <- matrix(rnorm(24), ncol = 3) |>
  (\(x) {colnames(x) <- c("X", "Y", "Z");x})()

mat1
#               X           Y          Z
#[1,] -0.62795166  0.18367824  0.5268557
#[2,] -0.04691673  1.77874162 -0.2302622
#[3,]  0.16261812  0.03768285  1.3974267
#[4,]  1.29230591  1.17622012  1.7636530
#[5,] -0.46355650 -0.55853581  0.4856014
#[6,]  0.30546323 -0.94561794 -0.2657389
#[7,] -0.08398871 -0.66518864  0.1516114
#[8,]  0.41036345  0.45203019  1.3766098

CodePudding user response:

You slightly missed the correct function.

matrix(rnorm(24), ncol = 3) |>
  `colnames<-`(c("X", "Y", "Z"))
#               X          Y           Z
# [1,]  1.9539043  0.5878187  0.56717400
# [2,]  0.3084174  0.8325519 -2.01892829
# [3,]  1.2961307  0.8870462  1.23968794
# [4,]  0.1692748 -0.4222143 -0.08322872
# [5,]  0.6739339  0.4442450  1.86393814
# [6,] -0.5023728  0.7051785 -0.63523642
# [7,] -0.4899054 -0.7428038  2.00537589
# [8,] -0.3942421 -0.0661493 -0.29608557

This works, because the assignment

colnames(m) <- c("X", "Y", "Z")

is actually also a function, and actually what you're doing is

m <- `colnames<-`(m, c("X", "Y", "Z"))
  • Related