[R] Is there a sexy way ...?

@vi@e@gross m@iii@g oii gm@ii@com @vi@e@gross m@iii@g oii gm@ii@com
Sat Sep 28 07:48:31 CEST 2024


You are, of course, correct, John. But in a strange way, many people end up
finding their wife or husband not so sexy after many years and find others
now seem to be.

R is not about sex and it was not the ideal choice of words.

I think what was wanted was something brief rather than taking many lines as
my second somewhat joking solution was. Even that, was written off the top
of my head and I now have thought a bit about ways to really simplify it.
For example, forget my commas and use spaces. Break the one long sentence up
without using regular expressions and showing a result already as a vector. 

And, frankly, often the best code involves writing one or more fairly small
functions with each being easy to understand. Add a few comments. And,
although it may not be the most efficient, it may LOOK somewhat simple and
direct.

Rolf did explain a bit more and clearly many of us solved a different
problem. But I note that using named lists may not have been the best choice
for working on his problem and choosing another form of data that allows
transposition of dimensions might have been a simpler task if that is what
he wanted.

Rolf suggested he did not already know some of the gimmicks used and he has
a point. He may want to learn more because of code like this and somewhat
similar but different for data.frames. This may not be useful for this app
with a requirement about factors but may motivate using other data formats
when useful.

> numbers <- 1:24
> print(numbers)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
> mat <- matrix(numbers, nrow=6, byrow=TRUE)
> print(mat)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
[4,]   13   14   15   16
[5,]   17   18   19   20
[6,]   21   22   23   24
> print(as.vector(mat))
 [1]  1  5  9 13 17 21  2  6 10 14 18 22  3  7 11 15 19 23  4  8 12 16 20 24
> mat <- matrix(numbers, nrow=6, byrow=FALSE)
> print(mat)
     [,1] [,2] [,3] [,4]
[1,]    1    7   13   19
[2,]    2    8   14   20
[3,]    3    9   15   21
[4,]    4   10   16   22
[5,]    5   11   17   23
[6,]    6   12   18   24
> print(as.vector(mat))
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
> mat <- matrix(numbers, ncol=6, byrow=TRUE)
> print(mat)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    2    3    4    5    6
[2,]    7    8    9   10   11   12
[3,]   13   14   15   16   17   18
[4,]   19   20   21   22   23   24
> print(as.vector(mat))
 [1]  1  7 13 19  2  8 14 20  3  9 15 21  4 10 16 22  5 11 17 23  6 12 18 24
> mat <- matrix(numbers, ncol=6, byrow=FALSE)
> print(mat)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    5    9   13   17   21
[2,]    2    6   10   14   18   22
[3,]    3    7   11   15   19   23
[4,]    4    8   12   16   20   24
> print(as.vector(mat))
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
> t(mat)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
[4,]   13   14   15   16
[5,]   17   18   19   20
[6,]   21   22   23   24
> mat <- matrix(numbers, nrow=6, byrow=TRUE)
> mat2 <- matrix(mat, nrow=4)
> print(mat)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
[4,]   13   14   15   16
[5,]   17   18   19   20
[6,]   21   22   23   24
> print(mat2)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1   17   10    3   19   12
[2,]    5   21   14    7   23   16
[3,]    9    2   18   11    4   20
[4,]   13    6   22   15    8   24
> df <- data.frame(a=1:6, b=7:12, c=13:18, d=19:24)
> print(df)
  a  b  c  d
1 1  7 13 19
2 2  8 14 20
3 3  9 15 21
4 4 10 16 22
5 5 11 17 23
6 6 12 18 24
> print(t(df))
  [,1] [,2] [,3] [,4] [,5] [,6]
a    1    2    3    4    5    6
b    7    8    9   10   11   12
c   13   14   15   16   17   18
d   19   20   21   22   23   24

-----Original Message-----
From: Sorkin, John <jsorkin using som.umaryland.edu> 
Sent: Saturday, September 28, 2024 12:01 AM
To: avi.e.gross using gmail.com; 'Rolf Turner' <rolfturner using posteo.net>;
r-help using r-project.org
Subject: Re: [R] Is there a sexy way ...?

"Sexy code" may get a job done and demonstrate the code's knowledge of a
programming language, but it often does this at the expense of clear, easy
to document (i.e. annotate what the code does), easy to read, and easy to
understand code. I fear that this is what this thread has developed "sexy"
but not easily understandable code. While I send kudos to all of you,
remember that sometimes simpler, while not as sexy can be better in the long
run. ;)

John David Sorkin M.D., Ph.D.
Professor of Medicine, University of Maryland School of Medicine;
Associate Director for Biostatistics and Informatics, Baltimore VA Medical
Center Geriatrics Research, Education, and Clinical Center;
PI Biostatistics and Informatics Core, University of Maryland School of
Medicine Claude D. Pepper Older Americans Independence Center;
Senior Statistician University of Maryland Center for Vascular Research;

Division of Gerontology and Paliative Care,
10 North Greene Street
GRECC (BT/18/GR)
Baltimore, MD 21201-1524
Cell phone 443-418-5382




________________________________________
From: R-help <r-help-bounces using r-project.org> on behalf of
avi.e.gross using gmail.com <avi.e.gross using gmail.com>
Sent: Friday, September 27, 2024 10:48 PM
To: 'Rolf Turner'; r-help using r-project.org
Subject: Re: [R] Is there a sexy way ...?

Rold,

We need to be clear on what makes an answer sexy! LOL!

I decided it was sexy to do it in a way that nobody (normal) would and had
not suggested yet.

Here is an original version I will explain in a minute. Or, maybe best a bit
before. Hee is the unformatted result whicvh is a tad hard to read but will
be made readable soon:

x <- list(`1` = c(7, 13, 1, 4, 10),
          `2` = c(2, 5,  14, 8, 11),
          `3` = c(6, 9, 15, 12, 3))

as.integer(unlist(strsplit(as.vector(paste(paste(x$`1`, x$`2`, x$`3`,
sep=","), collapse=",")), split=",")))

The result is: 7  2  6 13  5  9  1 14 15  4  8 12 10 11  3

After reading what others wrote, the following is more general one where any
number of vectors in a list can be handled:

as.integer(unlist(strsplit(as.vector(paste(do.call(paste, c(x, sep=",")),
collapse=",")), split=",")))

Perhaps a tad more readable is a version using the new pipe but for obvious
reasons, the dplyr/magrittr pipe works better for me than having to create
silly anonymous functions instead of using a period. You now have a
pipeline:

library(dplyr)

x %>%
  c(sep=",") %>%
  do.call(paste, .) %>%
  paste(collapse=",") %>%
  as.vector() %>%
  strsplit(split=",") %>%
  unlist() %>%
  as.integer()

And it returns the right answer!

- You start with x and pipe it as

- the first argument to c() and the second argument already in place is an
option to later use comma as a separator

- that is piped to a do.call() which takes that c() tuple and replaces the
second argument of period with it. You now have taken the original data and
made three text strings like so:
"7,2,6"   "13,5,9"  "1,14,15" "4,8,12"  "10,11,3"

- But you want all those strings collapsed into a single long string with
commas between the parts. Do another paste this time putting the substrings
together and collapsing with a comma. The results is:
"7,2,6,13,5,9,1,14,15,4,8,12,10,11,3"

- But that is not a vector and don't ask why!

- Now split that string at commas:
"7"  "2"  "6"  "13" "5"  "9"  "1"  "14" "15" "4"  "8"  "12" "10" "11" "3"

- and undo the odd list format it returns to flatten it back into a
character vector:
"7"  "2"  "6"  "13" "5"  "9"  "1"  "14" "15" "4"  "8"  "12" "10" "11" "3"

- Yep it looks the same but is subtly different. Time to make it into
integers or whatever:
7  2  6 13  5  9  1 14 15  4  8 12 10 11  3

Looked at after the fact, it seems so bloody obvious! And the chance of
someone else trying this approach, justifiably, is low, LOL!

One nice feature of the do.call is this can be extended like so:

x <- list(`1` = c(7, 13, 1, 4, 10),
          `2` = c(2, 5,  14, 8, 11),
          `3` = c(6, 9, 15, 12, 3),
          `4` = c( 101, 102, 103, 104, 105),
          `5` = c(-105, -104, -103, -102, -101))

Works fine and does this for the now five columns:

[1]    7    2    6  101 -105   13    5    9  102 -104    1   14   15  103
-103    4    8   12  104 -102
[21]   10   11    3  105 -101

My apologies to all who expected a more serious post. I have been focusing
on Python lately and over there, some things are done differently albeit I
probably would be using the numpy and pandas packages to do this or even a
simple list comprehension using zip:

# Python, not R.
 [ (first, second, third) for first, second, third in zip(*x)]

[(7, 2, 6), (13, 5, 9), (1, 14, 15), (4, 8, 12), (10, 11, 3)]

And, of course, that needs to be made into a list of individual items

# Python, not R.
[num
 for elem in [(first, second, third) for first, second, third in zip(*x)]
 for num in elem]

[7, 2, 6, 13, 5, 9, 1, 14, 15, 4, 8, 12, 10, 11, 3]

For any interested, you can combine python and R in the same program back
and forth on the same data inside what is still called RSTUDIO and if there
are times one allows a better or at least easier for you, way to do a
transformation, you can often mix and match.

-----Original Message-----
From: R-help <r-help-bounces using r-project.org> On Behalf Of Rolf Turner
Sent: Thursday, September 26, 2024 11:56 PM
To: r-help using r-project.org
Subject: [R] Is there a sexy way ...?


I have (toy example):

x <- list(`1` = c(7, 13, 1, 4, 10),
          `2` = c(2, 5,  14, 8, 11),
          `3` = c(6, 9, 15, 12, 3))
and

f <- factor(rep(1:3,5))

I want to create a vector v of length 15 such that the entries of v,
corresponding to level l of f are the entries of x[[l]].  I.e. I want
v to equal

    c(7, 2, 6, 13, 5, 9, 1, 14, 15, 4, 8, 12, 10, 11, 3)

I can create v "easily enough", using say, a for-loop.  It seems to me,
though, that there should be sexier (single command) way of achieving
the desired result.  However I cannot devise one.

Can anyone point me in the right direction?  Thanks.

cheers,

Rolf Turner

--
Honorary Research Fellow
Department of Statistics
University of Auckland
Stats. Dep't. (secretaries) phone:
         +64-9-373-7599 ext. 89622
Home phone: +64-9-480-4619

______________________________________________
R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide
https://www.r-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

______________________________________________
R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide
https://www.r-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list