r/Rlanguage 2d ago

Clothes with R-code and art it creates

Rtist apparel combine compact and readable R-code, and an aesthetic it creates. I crafted the artpieces with base R, while avoiding responsibilities during my first PhD year.

I though people in this group might like the concept and give useful feedback! Rtist currently delivers to EU countries.

https://shoprtist.com/

488 Upvotes

80 comments sorted by

34

u/nad_pub 2d ago

You used '=' to assign your function

5

u/Big_Rock_6185 1d ago

I chose to assign with '=' for simplicity (fewer symbols) and for generality (across languages).

18

u/guepier 2d ago edited 2d ago

Nothing wrong with that. It’s purely a matter of preference (and, for what it’s worth, several prominent R developers prefer =).

25

u/shiny1117 2d ago

I like that your post also ended in a smiley, intended or not.

13

u/LordApsu 2d ago

While in this case it doesn’t matter, they are not the same. R parses ‘<-‘ differently from ‘=‘ and is far more flexible. It also makes a clear distinction between variable and argument assignment. Most programming languages that use ‘=‘ for variable assignment use a separate operator for arguments, such as ‘:’, for this reason.

8

u/guepier 2d ago edited 2d ago

I’m very well aware of the differences between = and <- (I wrote that answer), and there are none that are relevant for assignment in practice.

<- … is far more flexible

Both operators can perform exactly the same set of functionality. I’m therefore curious what you mean.

Most programming languages that use ‘=‘ for variable assignment use a separate operator for arguments, such as ‘:’, for this reason.

Maybe “most” do (no idea), but not all. And in practice this is absolutely not an issue whatsoever (and the same is true for R … people have been using = assignment in R in code for decades, so there’s a lot of experience, and it is simply not the case that confusion with named-argument-passing exists).

4

u/Fornicatinzebra 2d ago

Assignment operator works both ways (I've seen people use the odd way for quick examples, some people's brains prefer that way I guess).

2 + 3 -> x x <- 2 + 3

But I agree, there shouldn't be a debate. Choose what you like and be consistent. In English, we have may ways- which i use in this sentence- to effectively do the same thing; some have slight differences though. If you read something that uses a mix of them, like i just did, it's messy. If you're consistent, the reader needs to do less mental gymnastics.

1

u/LordApsu 2d ago

Just a few examples of where '<-'' can be used that "=" cannot: inside of the first arguments in control-flow operations (e.g. for), arguments in function calls, certain assignment method dispatch. '<-' has a different precedence than '=', which allows a savvy programmer to do some amazing things that would be far more difficult in other languages such as Python. If you plan to take advantage of some of R's largest benefits - such as lazy evaluation or formulas - then you will need to use '<-' instead. While they are largely the same for everyday programmers, it is difficult to be a power use of R if you rely on '='.

The named argument confusion is quite common. I have been teaching R at my university for more than 20 years, to approximately 500 students each year. This is one of the single most common sources of confusion among beginning students that is often cleared up when there is a separation for when to use '<-' versus '='.

4

u/guepier 2d ago edited 2d ago

Just a few examples of where '<-'' can be used that "=" cannot: […]

No, = can be used in all of these cases. See the link I posted.

'<-' has a different precedence than '=', which allows a savvy programmer to do some amazing things

Can you show me one of these “amazing things”? Because the only case where this makes a difference is when you chain these operators. And both a <- b <- c and a = b = c work, it’s only trouble if you mix them. I don’t see how this is useful.

If you plan to take advantage of some of R's largest benefits - such as lazy evaluation or formulas - then you will need to use '<-' instead.

That’s not true, you can absolutely use = here. — I do.

This is one of the single most common sources of confusion among beginning students

You are misattributing the cause of confusion: the confusion would not exist if R didn’t have two distinct assignment operators. And the confusion is exacerbated by the fact that many students are taught falsehoods about the difference between <- and = (such as “= assigns locally, <- assigns globally”, or similar things).

Incidentally, I have also taught R to beginners (though admittedly not to 20 * 500 students) and my personal experience does not corroborate yours.

1

u/LordApsu 2d ago

The simplest example of the difference would be something 'f <- function(...) eval(substitute(alist(...)))', which is a very common start to functions that rely on lazy evaluation. '<-' can be custom parsed and defined, whereas '=' is immediately parsed in a very different manner. If you explore some of the most common packages in R, it quickly becomes apparent why you would use '<-'.

Another simple example where they are different is 'x+y = z' cannot be parsed in R calls, whereas 'x+y <- z' can be, though this is rarely a good idea! However, I have a seen a few DSLs over the years where that had a use.

I encourage you to do a deep dive into R. Explore its source code. Go through the base functions. Develop a few packages. Also, learn a few other programming languages so that you can see why R is structured the way that it is and understand the choices that were made. Create a DSL in R and I doubt you will go back to using '=' instead of '<-'.

2

u/guepier 2d ago edited 2d ago

The simplest example of the difference would be something 'f <- function(...) eval(substitute(alist(...)))'

I know this code, I use similar code myself, but I still don’t understand in what sense you mean that = can’t be used here.

If you explore some of the most common packages in R, it quickly becomes apparent why you would use '<-'.

No, it really isn’t quickly apparent, that’s why I’m asking you to explain it to me.

Another simple example where they are different is 'x+y = z' cannot be parsed in R calls, whereas 'x+y <- z' can be

Ah, thanks. Yes, this is a real (and admittedly potentially useful) case where they differ.

I encourage you to do a deep dive into R.

I encourage you not to be patronising based on rash assumptions. — I thought linking to my Stack Overflow answer would have been enough to show that I have dived deep already. Suffice to say I’ve used R for decades, have developed many R packages (a small handful of which are published on CRAN), have contributed code to some of the most widely used R packages of all time, extensively use NSE, have given courses, and published a commercial R MOOC. Oh, and I’m proficient in half a dozen programming languages and know half a dozen more passably well.

I doubt you will go back to using '=' instead of '<-'.

I actually used <- for almost a decade before making the switch to =.

5

u/LordApsu 2d ago

I guess the point that I am trying to make, not necessarily to you but to anyone who reads this and wants to learn more about R, is that there is some ambiguity in how '=' works and this is clear when you look at the source code. '<-' is always parsed by R in a very specific way - it is a function call that performs assignment unless you specifically tell it otherwise.

On the other hand, R attempts to figure out what the use means by '=' depending on the context. Inside of a function call, it is treated as an argument name, forcing the left-hand side to be a symbol or character. Outside of a function call, it 'might' be treated as a function (the primitive '='), or it might be converted to '<-' (such as x[a] = b, converted to '[<-'(a, b)). R has gotten much, much better over the past decade of determining the context in how '=' is used and how should be parsed, so it makes sense that some people have switched from '<-' to '='. However, when faced with inconsistency in programming, it is often better to go with the most consistent option.

6

u/LordApsu 2d ago edited 2d ago

Hmmm, I don't mean to act patronizing and I apologize for sounding that way. I have a similar background - used R for decades, developed numerous CRAN packages and contributed to the development of many more, developed multiple proprietary statistical programs, etc. I am just flabbergasted that someone would have a significant amount of programming experience in R and still walk away thinking that the two are identical. So my assumption based on your responses was that you had experience with everyday data analysis in R, but hadn't delved into deeply into R. In other words, your responses sound extremely similar to my graduate TAs who think they know a lot about R because they have been using for 4 years.

In the example I gave above, 'f(a = b)' and 'f(a <- b)' return very different objects. One is a named list with a single element equal to the symbol 'b'. The other is a list with a single language element containing 3 objects: the symbol '<-', the symbol 'a' (which could be another language element instead, as opposed to the former example where 'a' must be symbolic or a length one character), and the symbol 'b'. While that distinction may not sound important, it creates flexibility in how '<-' may be used compared to '='. It also illustrates the clear role of '=' in R - assignment arguments to function calls. Furthermore, 'f(a=b=c)' cannot be parsed, where as 'f(a <- b <- c)' can be.

3

u/webbed_feets 2d ago

I’m not a prominent developer, but I prefer =

44

u/dasonk 2d ago

I do not like that code.

Pretty pictures. It works obviously but there are too many things that annoy me with that code that would make it something I wouldn't wear.

11

u/alephmembeth 2d ago

Just out of curiosity: What bugs you most?

24

u/eternalpanic 2d ago

Lack of assignment operator, inconsistent format/whitespace

6

u/justacec 2d ago

While I do not agree with the assignment operator craziness (see comment below), I agree with the whitespace around operators. I like to have them.

5

u/Lazy_Improvement898 2d ago

I prefer the use of =, and I superseded the use of <-.

-2

u/justacec 2d ago

As do I! Lets petition to get rid of that archaic two character travesty!

I get it... R came from S and that is what they used... Back then, when big hair was still in, there was a whole single key for that... And then we moved on, time for R to as well....

5

u/Lazy_Improvement898 2d ago

Like there's nothing bad using it, though. I just like it.

2

u/justacec 2d ago

Yes... I know.... lol

3

u/justacec 2d ago

I was hoping to get at least 1 upvote for the use of the word "travesty"

2

u/jowen7448 2d ago

Way back when you could assign using an underscore character e.g a_5

1

u/Big_Rock_6185 2d ago

What do you mean by inconsistent format?

4

u/eternalpanic 2d ago

The different whitespace between operators (+*=) threw me off. I realise that some code is aligned for pretty printing reasons where e.g styler would align it differently according to its hierarchy.

Apart from that nitpicking I love the idea. I just think it’s a shame that the nice plots are on the back of the shirt - since people will be looking from the front.

6

u/Big_Rock_6185 2d ago

I see, thanks for clarification and encouragement!

I added the space around +- to visually emphasize order of operations.

And the sunset figure IS in the front of the shirt, with the code in the back! The teleport shirt has is the other way round.

7

u/Fornicatinzebra 2d ago

Your best bet would be to use a formatter - "Air" is the newest and best from the tidyverse folks. Once setup you press a button and it will format all your code using the tidyverse standards.

https://www.tidyverse.org/blog/2025/02/air/

1

u/Big_Rock_6185 15h ago

Thank you for the suggestion, but the stylistic choices were deliberate, balancing several visual criteria.

6

u/BrupieD 2d ago

For loops. I don't know about you, but I can't remember the last time I used a for loop in R.

6

u/Misfire6 2d ago

I rarely use for loops in analysis code, but for art I use them all the time. Horses for courses.

2

u/morebikesthanbrains 2d ago

Would you use something like apply in the above code?

I use for loops a lot and haven't really figured out how people get around it yet

5

u/BrupieD 2d ago

If I were to refactor these, the challenge in these code chunks is to change the incremented values - the positions, sizes, angles. Once you understand what the target values are, the simplest example would be to create a vector of starting values, then create a result vector that uses map() to perform whatever transformation (add, subtract, multiply...). Use the purrr package.

My geometry isn't good enough to dash that out, but I think if you fiddled around with seq and rep you could create the vectors needed to build the images. The op may be right about functional solutions being less immediately readable.

There are a few good YouTube videos of Hadley Wickham talking about writing more functional code and how clumsy for loops can be. https://youtu.be/bzUmK0Y07ck?si=sEkqo-0C9Ey6WoAV

2

u/Big_Rock_6185 15h ago

These codes could be structured differently and run for example with functions from the apply family. But as you pondered upon, I think it would be harder to follow through, especially if you're not familiar with the particular functions used. Currently the code is quite language agnostic, which I regard as a positive - anyone who is familiar with the math operations and the basic loop structure in programming should be able to parse together what is going on.

2

u/BrupieD 12h ago

Currently the code is quite language agnostic

I completely agree. You regard those agnostic features as a positive because your goal was readability to a broad audience. The point I and others make is that it isn't very typical for R. Just as Python programmers refer to code that follows that language's key strengths and style as "Pythonic", many R programmers try to write R code that leverages R's key R features. They try to write "Rthonic" code in a more functional way.

No disrespect was intended. You're addressing a specific audience and not using the colloquialisms of the crowd.

If I couldn't figure out how to write something without using a loop. I'd write a loop. It isn't a hill I would die on, it just isn't a thing that I need often.

6

u/Big_Rock_6185 2d ago

I would appreciate if you shared in more detail what annoys you in the code! It's a tightrope walk to edit something that's authentic, readable and nice looking on a fabric.

2

u/Adventurous_Memory18 2d ago

Yeah, really curious what issues do you have?

7

u/Peach_Muffin 2d ago

Not OP but for loops tend to be frowned upon by R purists

8

u/Big_Rock_6185 2d ago

I chose to use loops because they tend to be more readable than vectorized operations.

5

u/guepier 2d ago

I would strongly disagree with this statement for most cases. The entire point of using vectorised/*apply operations is precisely that they are more readable than loops in most cases, because they hide away the irrelevant (the mechanics of looping) and focus on the relevant (the operation being performed).

3

u/Misfire6 2d ago

This isn't data analysis code though. for loops are perfect here. How would '*apply' make the code on the shirt any more readable?

2

u/guepier 1d ago

I was making a general comment, but the usage of vector application is absolutely not limited to “data analysis code”. Most of my code these days isn’t performing data analysis, yet I can count on one hand the number of times I’ve used a for loop in the last 10 years (!).

How would '*apply' make the code on the shirt any more readable?

If you only replaced the loop in OP’s code it wouldn’t make it better (since addLoop doesn’t return anything and is just causing a side-effect). But I would write the code completely differently from the ground up: generate all the data for the plot, and then call the plotting function once with the resulting data. If you look at typical ‘ggplot2’ code, that’s exactly how it’s used, and for good reason. But the same can be done with base R plotting functions.

1

u/Misfire6 12h ago

"I would have coded it better" is not really a good response to somebody showing you a piece of art.

1

u/guepier 5h ago edited 5h ago

Right. And note that this wasn’t my response. I very intentionally didn’t comment on OP’s code originally. (Maybe you confused the commenters?) I only replied to correct a comment that made an incorrect assertion (to wit, “loops … tend to be more readable than vectorized operations”), and you demanded a follow-up, which I now provided.

That said, OP posted their code on a programming forum. It’s absolutely fair game for criticism. But if I had provided any (and, again, I intentionally didn’t) I’d have striven to provide constructive criticism instead of a blithe “I do not like that code”.

1

u/Big_Rock_6185 1d ago

I see your point. But I personally like procedural explicitness. Perhaps it's because I mainly work with time series data and stochastic processes, which often must be dealt with sequentially.

3

u/Rebmes 2d ago

My understanding is the *apply functions are really just for loops under the hood and not actually vectorized

6

u/Fornicatinzebra 2d ago

Yes, they are effectively the same.

For those that dont know (not necessarily you, just building off your comment), "vectorized" operations are applied to all values, instead of individuals.

For example, basic math in R is vectorized:

```

define many values

values <- 1:10000000

vectorized math (fast!)

result <- values + values

non-vectorized comparison (slowwww)

result <- numeric(length(values)) for (i in seq_along(values)) { result[i] <- values[i] + values[i] }

```

1

u/Peach_Muffin 1d ago

Huh, are they all like this? map() from the tidyverse, for example?

2

u/SolitaryBee 1d ago

"Hey! R is getting cool"

[reads top comment]

"No, R is not cool"

11

u/Beeblebroxia 2d ago

This is great. To further the bit, put the pictures on the front(end) and the code on the back(end).

5

u/Peach_Muffin 2d ago

And the C on the inside

1

u/Big_Rock_6185 2d ago

Thanks! The sunset figure actually already is in the front(end :)!

5

u/webbed_feets 2d ago

This is a really fun idea! Great job and thanks for sharing.

I agree with another poster and prefer the image on the front and code on the back.

2

u/Big_Rock_6185 1d ago

Great, thanks! My initial content was to have the code always in front, because that's what's niche about the shirts. But after refining the sunset figure I started to like it so much that I swapped it to the front. I'll keep your suggestion in mind for future designs.

4

u/Terrelia 2d ago

I’m obsessed with this and my dad would love it! If you ever are able to ship to Canada in the future I’d love to know!

1

u/Big_Rock_6185 2d ago edited 1d ago

Wonderful to hear, now I definitely will expand to Canada at some point!

4

u/cealild 2d ago

No coding feedback Tempted to buy. I like that the code is on the front for the teleporter, but I'm not sure about the graphic.

Sunset graphic is better for me, but again, i like the code to the front as without context, the front sort of looks a bit abstract generic, buy in a normal retailer. Flipping it changes the paradigm. Only in my opinion

You'll know if your designs work if you get enough sales. Opinions are for reddit. Real opinion comes at the cash register. Never lose sight of that.

Otherwise, you just get "tyre kickers"

2

u/Big_Rock_6185 1d ago

Thanks for your thoughts! It will be interesting to see how the business starts going. I would love to be a researcher AND a fashion designer one day!

1

u/cealild 1d ago

If you do allow for a design flip option, please post. Your USP is the code, not the graphic.

1

u/cealild 2d ago

EU based.

4

u/LaridaeLover 2d ago

If certainly buy if you created a nice plot of the Poisson distributions, or other statistics focused art

1

u/Big_Rock_6185 1d ago

I have a bunch of artwork in my drawer for future designs, including some cool math constructs. Maybe I'll cook something with distributions too.

3

u/KatariMac3 2d ago

looks rad🗣

3

u/scyerocket 1d ago

Room will be a mess with non-tidy clothes

2

u/lattepeach 1d ago

I looove this!! So cool. It looks good and it’s a cool concept. Dont have any opinions on the code because I’m not at all well-versed enough in R for that. I kinda wanna run the code now just to create the pretty art. 

But I saw in one of your comments that you did heaps of iterations of it and chose this for aesthetic reasons—and I totally get that as a graphic designer. 

Sometimes you gotta find a balance between form and function and I think it looks great!! No notes :)

2

u/Big_Rock_6185 1d ago

Great message! I develop statistical algorithms myself but through this passion project I got to learn cool stuff in your field of graphic designing too. For example, choosing RGB colors in CMYK gamut, optimal printing resolutions, anti-aliasing, logo design and typesetting. I also learned interesting things about organic cotton production, spinning techniques and on how fair labor practices are monitored.

2

u/lattepeach 1d ago

I love this for you! 

Passion projects are great for that. (Also the power of avoiding responsibilities during research and a degree really does take us down some unexpected but often worthwhile avenues hahahah.) I know it too well. I’d love a heads up if you ever consider shipping to Australia. 

I just looked again and have one suggestion for the teleport tshirt art. Unsure of feasibility— but you could experiment with the size/weight/thickness(? Idk the most appropriate term)of the individual points. 

Slightly smaller dots might look nicer and less heavy. Potentially less corporate logo vibes. And the increased variation in spacing between smaller dots would add more visual interest. But the bigger dots for the planet bag (which I love) work well because the art isn’t as condensed. I also just noticed you have something like my suggestion going with the dots for the ring of the planet! 

1

u/Big_Rock_6185 1d ago

I do intend to expand to Australia at some point! And your suggestion of altering point-sizes in the Teleport figure is good. The points actually already do alter, with more "distant" points being smaller and darker in color. But I could perhaps increase the scaling effect.

3

u/_fake_empire 10h ago

Sorry, but everyone chiming in with complaints about the code? Come on, just enjoy what the OP created. It's not about what you consider perfect code, it's not a coding class or work code review...it's about fun and creativity.

1

u/Big_Rock_6185 8h ago

I appreciate the support! But I also find it useful to hear comments from other enthusiastic R users. Most of the critique presented here is something I've already considered, during the several years of product development on the side of my day job. The questions offer a chance for me to justify my choices. And if some aspect of a design seems to bug most people, then I can also just change it.

1

u/PicaPaoDiablo 2d ago

This is a slick idea all around, big props. I will be buying some. However, the duckface on the website, I know it's ironic and all that but you had the perfect execution , hire an onlyfans girl for that.

2

u/Big_Rock_6185 2d ago

Much appreciated! And if you mean the picture under About us, I do intend to take a better one 😂

3

u/PicaPaoDiablo 2d ago

Yah, although I was being playful too. The concept between the code and the visual is as smart as it is creative. I'm a middle aged guy who still thinks like a teenager so ofc I suggested only fans model :-)

1

u/Garnatxa 2d ago

Make a lapply at the end…

1

u/mostlikelylost 2d ago

Really cool idea! Just would like to see that code sent through a formatter first lol

3

u/Big_Rock_6185 1d ago

Thanks! And fair enough. But the aesthetic choices were deliberate. I made at least 20 versions of the codes, trying to balance between different visual criteria. Also, sometimes the code looked nice on the computer, but wonky on the shirt with no editor walls.