A small food survey – Results

Late last year, we conducted a small (non-representative) food survey: Which food is most (un-)popular, are there different “food types”, or do food preferences correlate with traveling activities?

The results

Now, we present our findings. Most of the 60 participants in total were between 20 – 40 years old. A strikingly high fraction of more than 15 % indicated a vegan nutrition. The ratio between female and male participants was even. On average, the participants liked around 60 % of the prompted food items. (The links below are in German only, but the graphics speak for themselves!)

Wholemeal buns, oranges and chocolate were the most popular food items. Around 17 % had never eaten algae. For some of the prompted food items, positive preference changed to aversion. Noticeably, this change of mind was mainly indicated for vegetables, with olives leading the way. Overall, vegan participants were more open to the prompted food items than others.

Finally, there were certain connections between food preference and personal attributes, like favorite colors or visited continents. On the one hand, for example, ginger was particularly popular among people who have been to Northern America. On the other hand, non-wholemeal buns were unpopular among people travelling South America. For more results and infos, please click one of the adjacent links.

See you soon and best!

dqrng v0.1.0: breaking changes

A new version of dqrng has made it onto the CRAN servers. This version brings two breaking changes, hence the “larger than usual” change in version number:

  • An integer vector instead of a single int is used for seeding (Aaron Lun in #10)
    • Single integer seeds lead to a different RNG state than before.
    • dqrng::dqset_seed() expects a Rcpp::IntegerVector instead of an int
  • Support for Mersenne-Twister has been removed, Xoroshiro128+ is now the default.

The first change is motivated by the desire to provide more than 32 bits of randomness as seed to the RNG. With this possibility in place, the previously used scrambling of the single 32 bit integer did not make much sense anymore and was therefore removed. The new method generateSeedVectors() for generating a list of random int vectors from R’s RNG can be used to generate such seed vector.

The second change is related to a statement in R’s manual: Nor should the C++11 random number library be used …. I think that relates to the implementation-defined distributions and not the generators, but in general one should follow WRE by the letter. So std::mt19937_64 has to go, and unfortunately it cannot be replaced by boost::random::mt19937_64 due to a not-merged pull request. Instead of shipping a fixed version of MT I opted for removal since:

  • MT is known to fail certain statistical tests.
  • MT is slower than the other generators.
  • MT was the only generator that does not support multiple streams of random numbers necessary for parallel operations.

The other usage of random from C++11 was the default initialization, which used std::random_device. This is now unnecessary since the initial state of the default RNG is now based on R’s RNG, using the techniques developed for generateSeedVectors().

dqrng v0.0.5: New and updated RNGs

A new version of dqrng has made it onto the CRAN servers after a brief hick-up. Thanks to the CRAN team in general and Uwe Ligges in particular for their relentless efforts.

This versions adds a new RNG to be used together with the provided distribution functions: The 64 bit version of the 20 rounds Threefry engine (Salmon et al., 2011 <doi:10.1145/2063384.2063405>, http://www.thesalmons.org/john/random123/) from the sitmo package. Thanks to James Balamuta for adding the C++11 version of Threefry to his package.

In addition, the PCG headers have been updated to the most recent version. Thanks to Aaron Lun for the heads-up and the pointer to two packages on BioConductor that are using dqrng: DropletUtils and scran.

There have also been two more technical changes: On the one hand the package is now prepared for the future, since -DSTRICT_R_HEADERS is added to PKG_CPPFLAGS in src/Makevars.

On the other hand I have added unit tests for the C++ interface. I first tried Catch since I am using testthat already. However, I did not like compiling test code into the final library. Instead I have added C++ files that are compiled using Rcpp::sourceCpp() and run during the test. This is also a more realistic test of the C++ interface.

A small food survey

This post is about a small side project: A (non-representative) food survey. Which foods are (un-)popular? Do food preferences correlate with traveling activities? Are there different “food types”? And many more.

The idea

During lunch, naturally, we often talk about food. About different tastes, likes and dislikes. How (un-)popular are certain foods, are there different “types” of eaters, or do travelling destinations correlate with food preferences? To shed some light onto these questions, because we did not find accessible studies, and with the tools of web programming and statistics at hand, we decided to start a fun side project.

Now we present you a small food survey! Since we do not select a random sample, the survey does not allow representative statements. Its findings only hold for the group of participants, not for Germany and certainly not on a global scale. Nevertheless, we hope that both we and you enjoy our survey and find some interesting connections.

Click here to start the survey (in German only)!

Additional infos

After going through three medium-short pages of questions you will see some preliminary results, and how your answers compare to those of others. Moreover:

  • Of course, all data are fully anonymous and will not be used for any commercial purpose.
  • Throughout the course of the survey, we will update this blog post to keep you informed.
  • Please feel free to share this survey as you wish.

If there are any questions or comments, please send us a message. Enjoy!

dqsample: A bias-free alternative to base::sample()

For many tasks in statistics and data science it is useful to create a random sample or permutation of a data set. Within R the function base::sample() is used for this task. Unfortunately this function uses a slightly biased algorithm for creating random integers within a given range. Most recently this issue has been discussed in a thread on R-devel, which is also the motivation of the dqsample package. Currently dqsample is not on CRAN, but it can be installed via drat:

Example for the bias

When sampling many random integers the density of odd and even numbers should be roughly equal and constant. However, this is not the case with base::sample:

plot of chunk base

Or with slightly different parameters:

plot of chunk base-oszi

This particular example for the bias was found by Duncan Murdoch.

In dqsample the algorithm suggested by Daniel Lemire (2018, <arXiv:1805.1094>) is used. With this algorithm there is no observable bias between odd and even numbers:

plot of chunk dqsample

Where does the bias come from?

Internally the base::sample() function needs uniformly distributed random integers in an half-open range [0, n). In order to do so, R uses random floating point numbers that are uniformly distributed in [0, 1), multiplies by n and truncates the result to the next smaller integer. This method would be fine, if the random numbers used as starting point would be real numbers in the mathematical sense. However, this is not the case here.

The default random-number generator in R is a 32 bit version of the Mersenne-Twister. It produces random integers uniformly distributed in [0, 2^32), which are then divided by 2^32 to produce doubles in [0, 1). We can now invert the procedure described above to see how many integers are mapped to a certain result. For example, we could simulate rolling ten dice using sample(6, 10, replace = TRUE). Since 2^32 is not a multiple of six, the distribution cannot be completely even:

We see that both one and four are very slightly less likely than the other numbers. This effect gets much more pronounced as the number of items increases from which one can choose. For example, we can use the m from above to see how that uneven distribution of odd and even numbers came about:

Here we see that while only two integers map to any odd number, there are three integers mapped to the even numbers. This pattern shifts half way through the possible results, making the odd numbers more likely, leading to the first image displayed above. As one goes away from m, these pattern shifts occur more rapidly, leading to the oscillatory behaviour seen in the second image. As one moves further away from m, these oscillations happen so rapidly, that a density plot of odd and even numbers looks constant, but the bias is still there. For example, for m - 2^20 one such pattern shift happens between 982 and 983:

Below this point, even numbers are more likely than odd numbers. After this point, the pattern is reversed.

Conclusion

The algorithm used by base::sample() is biased with non-negligible effects when sampling from large data sets. The dqsample package provides an unbiased algorithm for the most common cases. It can be used as a drop-in replacement for the functionality provided by base::sample().