data.frame(data.frame(numbers=c(1,2,3)), data.frame(letters=c("a", "b", "c"))) makes a data frame:
numbers letters 1 1 a 2 2 b 3 3 c
data.frame(data.frame(numbers=c(1,2,3)), data.frame(letters=c("a", "b", "c", "d"))) does not:
Error in data.frame(data.frame(numbers = c(1, 2, 3)), data.frame(letters = c("a", : arguments imply differing number of rows: 3, 4
data.frame(data.frame(numbers=c(1,2,3)), data.frame(letters=c("a", "b", "c", "d", "e","f"))) makes a data frame, but not the one I'd expect:
numbers letters 1 1 a 2 2 b 3 3 c 4 1 d 5 2 e 6 3 f
What's the reasoning behind this? I get that if one column is a factor of the other (numerically speaking) it will just repeat the content to make it fit. But I'm not sure why you'd want to do that as a default/without an error, or what about the structure of data frames/R made this seem like a good idea.
Yes, this is R's famous recycling rule... from the canon: "Shorter vectors in the expression are recycled as often as need be (perhaps fractionally) until they match the length of the longest vector." and "Any short vector operands are extended by recycling their values until they match the size of any other operands." It's not specific to data frames, but anything to do with vectors, and even functions.
So it's normal and intended for R, but not everyone agrees it's ideal (cf. this reaction, at 'Vector Operations'). The reason why it exists is because a vector in R is an ordered set of measurements (which can be useful to repeat) rather than a geometrical position or a physical state, as a vector is defined in other domains.
If R suspects recycling is unintended, i.e. when one length is not an integer multiple of another, then you'll get a warning. For example,
c(1:3)/c(3:6)
gives a warning, butc(1,2)/c(3:6)
gives no warning. If it seems like you know what you're doing then it will happen silently. Sometimes it's helpful to recycle, sometimes it'll wreck everything...