{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Functional Programming" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Functional programming refers to a specialized way of writing code so that 'side effects' are avoided, making the outcome of the code easier to predict. It is 'declarative' - functions are given as expressions, as opposed to 'imperative', where commands are issued to change the state of the program (e.g. change the value of variables by assignment). Historically, programming has been imperative, but the notion of functional programming is gaining ground lately, especially because of its connection to paralellization and distributed computing.\n", "\n", "We won't discuss the methodology in detail, but we will cover the basic R tools for functional programming - tools that allow us to apply functions across data structures. These tools allow us to avoid looping by extending the ability to vectorize operations." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## R apply" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`apply` maps a function to a matrix:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " [,1] [,2] [,3]\n", " [1,] -1.88415809 -0.09135793 -0.04933136\n", " [2,] 0.27581447 0.59928155 -0.01019772\n", " [3,] 0.23509325 -1.38182122 -1.49150530\n", " [4,] -1.29592234 -0.10180487 -1.62481563\n", " [5,] 0.31163838 -1.16070666 0.60327878\n", " [6,] 0.23685780 0.80313813 1.49028075\n", " [7,] -0.51883441 0.30667497 0.81876505\n", " [8,] -0.01050835 -1.49125738 1.67045716\n", " [9,] -0.17823674 0.50897338 -1.11499439\n", "[10,] 1.00128144 0.70455616 -0.23839229\n" ] } ], "source": [ "m<-matrix(rnorm(30),ncol=3,nrow=10)\n", "print(m)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
    \n", "\t
  1. -0.674949128760326
  2. \n", "\t
  3. 0.288299434064387
  4. \n", "\t
  5. -0.87941108856336
  6. \n", "\t
  7. -1.00751428266863
  8. \n", "\t
  9. -0.0819298347992709
  10. \n", "\t
  11. 0.84342555958658
  12. \n", "\t
  13. 0.202201872370568
  14. \n", "\t
  15. 0.0562304744778094
  16. \n", "\t
  17. -0.261419251214308
  18. \n", "\t
  19. 0.489148438901616
  20. \n", "
\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item -0.674949128760326\n", "\\item 0.288299434064387\n", "\\item -0.87941108856336\n", "\\item -1.00751428266863\n", "\\item -0.0819298347992709\n", "\\item 0.84342555958658\n", "\\item 0.202201872370568\n", "\\item 0.0562304744778094\n", "\\item -0.261419251214308\n", "\\item 0.489148438901616\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. -0.674949128760326\n", "2. 0.288299434064387\n", "3. -0.87941108856336\n", "4. -1.00751428266863\n", "5. -0.0819298347992709\n", "6. 0.84342555958658\n", "7. 0.202201872370568\n", "8. 0.0562304744778094\n", "9. -0.261419251214308\n", "10. 0.489148438901616\n", "\n", "\n" ], "text/plain": [ " [1] -0.67494913 0.28829943 -0.87941109 -1.00751428 -0.08192983 0.84342556\n", " [7] 0.20220187 0.05623047 -0.26141925 0.48914844" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Get the mean of the rows, returned as a vector \n", "apply(m,1,mean)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
    \n", "\t
  1. -0.18269745842911
  2. \n", "\t
  3. -0.130432387900508
  4. \n", "\t
  5. 0.00535450434813664
  6. \n", "
\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item -0.18269745842911\n", "\\item -0.130432387900508\n", "\\item 0.00535450434813664\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. -0.18269745842911\n", "2. -0.130432387900508\n", "3. 0.00535450434813664\n", "\n", "\n" ], "text/plain": [ "[1] -0.182697458 -0.130432388 0.005354504" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Get the mean of the columns, returned as a vector \n", "apply(m,2,mean)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Work!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Find the sum of each of the columns of the matrix m.\n", "* Find the product of each of the rows of the matrix m.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Custom Functions and `apply`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Any function that acts on a vector can be applied to the rows or columns of a matrix using `apply`. For example:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\t\n", "\t\n", "\t\n", "\n", "
3.55005170850.07607362400.05526883721.67941471700.09711847760.05610161870.26918914150.00011042550.03176833631.0025645300
0.0083462720.3591383751.9094298850.0103642321.3472399590.6450308520.0940495382.2238485730.2590539050.496399383
0.00243358330.00010399352.22458805242.64002584000.36394528982.22093670910.67037621012.79042710781.24321250080.0568308829
\n" ], "text/latex": [ "\\begin{tabular}{llllllllll}\n", "\t 3.5500517085 & 0.0760736240 & 0.0552688372 & 1.6794147170 & 0.0971184776 & 0.0561016187 & 0.2691891415 & 0.0001104255 & 0.0317683363 & 1.0025645300\\\\\n", "\t 0.008346272 & 0.359138375 & 1.909429885 & 0.010364232 & 1.347239959 & 0.645030852 & 0.094049538 & 2.223848573 & 0.259053905 & 0.496399383\\\\\n", "\t 0.0024335833 & 0.0001039935 & 2.2245880524 & 2.6400258400 & 0.3639452898 & 2.2209367091 & 0.6703762101 & 2.7904271078 & 1.2432125008 & 0.0568308829\\\\\n", "\\end{tabular}\n" ], "text/markdown": [ "1. 3.5500517085214\n", "2. 0.00834627218414201\n", "3. 0.00243358325091888\n", "4. 0.076073623981617\n", "5. 0.359138374577541\n", "6. 0.000103993499754627\n", "7. 0.0552688372335802\n", "8. 1.90942988523083\n", "9. 2.22458805237419\n", "10. 1.67941471695042\n", "11. 0.010364232207734\n", "12. 2.64002584003171\n", "13. 0.0971184776035244\n", "14. 1.34723995885993\n", "15. 0.363945289825967\n", "16. 0.0561016186653326\n", "17. 0.645030852184803\n", "18. 2.22093670911309\n", "19. 0.269189141470801\n", "20. 0.0940495383642278\n", "21. 0.670376210134819\n", "22. 0.000110425462972441\n", "23. 2.22384857296027\n", "24. 2.79042710783456\n", "25. 0.0317683363166527\n", "26. 0.259053905264377\n", "27. 1.24321250079777\n", "28. 1.00256453003707\n", "29. 0.496399383429726\n", "30. 0.0568308829099294\n", "\n", "\n" ], "text/plain": [ " [,1] [,2] [,3] [,4] [,5] [,6]\n", "[1,] 3.550051709 0.0760736240 0.05526884 1.67941472 0.09711848 0.05610162\n", "[2,] 0.008346272 0.3591383746 1.90942989 0.01036423 1.34723996 0.64503085\n", "[3,] 0.002433583 0.0001039935 2.22458805 2.64002584 0.36394529 2.22093671\n", " [,7] [,8] [,9] [,10]\n", "[1,] 0.26918914 0.0001104255 0.03176834 1.00256453\n", "[2,] 0.09404954 2.2238485730 0.25905391 0.49639938\n", "[3,] 0.67037621 2.7904271078 1.24321250 0.05683088" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "apply(m,1,function(x) x*x)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
    \n", "\t
  1. 3.56083156395646
  2. \n", "\t
  3. 0.435315992058913
  4. \n", "\t
  5. 4.18928677483859
  6. \n", "\t
  7. 4.32980478918986
  8. \n", "\t
  9. 1.80830372628942
  10. \n", "\t
  11. 2.92206917996323
  12. \n", "\t
  13. 1.03361488996985
  14. \n", "\t
  15. 5.01438610625781
  16. \n", "\t
  17. 1.5340347423788
  18. \n", "\t
  19. 1.55579479637673
  20. \n", "
\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 3.56083156395646\n", "\\item 0.435315992058913\n", "\\item 4.18928677483859\n", "\\item 4.32980478918986\n", "\\item 1.80830372628942\n", "\\item 2.92206917996323\n", "\\item 1.03361488996985\n", "\\item 5.01438610625781\n", "\\item 1.5340347423788\n", "\\item 1.55579479637673\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 3.56083156395646\n", "2. 0.435315992058913\n", "3. 4.18928677483859\n", "4. 4.32980478918986\n", "5. 1.80830372628942\n", "6. 2.92206917996323\n", "7. 1.03361488996985\n", "8. 5.01438610625781\n", "9. 1.5340347423788\n", "10. 1.55579479637673\n", "\n", "\n" ], "text/plain": [ " [1] 3.560832 0.435316 4.189287 4.329805 1.808304 2.922069 1.033615 5.014386\n", " [9] 1.534035 1.555795" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "apply(m,1,function(x) x%*%x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that `apply` returns an object of the appropriate dimension automagically. In the first example, the multiplication operator is the element-by-element product, so `apply` give us a matrix whose rows are the result of multiplying each of the 3 rows by itself. In the second example, the multiplication operator is a dot product, so `apply` returns a 10-dimensional vector with each entry the squared norm of the 3-dimensional row vector." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Work!" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "Use `apply` to count the number of negative values in each column of m. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `sapply` and `lapply`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "R has several other versions of apply, for specific types of input and output data structures. Two of the most common are `lapply` and `sapply`. `sapply` can operate on either a list or a vector and returns a list or vector, respectively. `lapply` can operate on either a list or a vector, but returns a list.\n", "\n", "For example:\n" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
    \n", "\t
  1. 2
  2. \n", "\t
  3. 4
  4. \n", "\t
  5. 6
  6. \n", "\t
  7. 8
  8. \n", "\t
  9. 10
  10. \n", "\t
  11. 12
  12. \n", "\t
  13. 14
  14. \n", "\t
  15. 16
  16. \n", "\t
  17. 18
  18. \n", "\t
  19. 20
  20. \n", "
\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 2\n", "\\item 4\n", "\\item 6\n", "\\item 8\n", "\\item 10\n", "\\item 12\n", "\\item 14\n", "\\item 16\n", "\\item 18\n", "\\item 20\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 2\n", "2. 4\n", "3. 6\n", "4. 8\n", "5. 10\n", "6. 12\n", "7. 14\n", "8. 16\n", "9. 18\n", "10. 20\n", "\n", "\n" ], "text/plain": [ " [1] 2 4 6 8 10 12 14 16 18 20" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v<-1:10\n", "sapply(v,function(x) x*2)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
    \n", "\t
  1. 2
  2. \n", "\t
  3. 4
  4. \n", "\t
  5. 6
  6. \n", "\t
  7. 8
  8. \n", "\t
  9. 10
  10. \n", "\t
  11. 12
  12. \n", "\t
  13. 14
  14. \n", "\t
  15. 16
  16. \n", "\t
  17. 18
  18. \n", "\t
  19. 20
  20. \n", "
\n" ], "text/latex": [ "\\begin{enumerate}\n", "\\item 2\n", "\\item 4\n", "\\item 6\n", "\\item 8\n", "\\item 10\n", "\\item 12\n", "\\item 14\n", "\\item 16\n", "\\item 18\n", "\\item 20\n", "\\end{enumerate}\n" ], "text/markdown": [ "1. 2\n", "2. 4\n", "3. 6\n", "4. 8\n", "5. 10\n", "6. 12\n", "7. 14\n", "8. 16\n", "9. 18\n", "10. 20\n", "\n", "\n" ], "text/plain": [ "[[1]]\n", "[1] 2\n", "\n", "[[2]]\n", "[1] 4\n", "\n", "[[3]]\n", "[1] 6\n", "\n", "[[4]]\n", "[1] 8\n", "\n", "[[5]]\n", "[1] 10\n", "\n", "[[6]]\n", "[1] 12\n", "\n", "[[7]]\n", "[1] 14\n", "\n", "[[8]]\n", "[1] 16\n", "\n", "[[9]]\n", "[1] 18\n", "\n", "[[10]]\n", "[1] 20\n" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v<-1:10\n", "lapply(v,function(x) x*2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Aside on Lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You may be wondering what is the difference between lists and vectors? Well, vectors are lists - but they are a specific type of list that contains only numbers. Lists can contain different types of objects. Consider the following:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
    \n", "\t
    1. \n", "\t
    2. 1
    3. \n", "\t
    4. 2
    5. \n", "\t
    6. 3
    7. \n", "\t
    8. 4
    9. \n", "\t
    10. 5
    11. \n", "\t
    12. 6
    13. \n", "\t
    14. 7
    15. \n", "\t
    16. 8
    17. \n", "\t
    18. 9
    19. \n", "\t
    20. 10
    21. \n", "
    \n", "
  1. \n", "\t
  2. \n", "\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\n", "
    -1.88415809-0.09135793-0.04933136
    0.27581447 0.59928155-0.01019772
    0.2350933-1.3818212-1.4915053
    -1.2959223-0.1018049-1.6248156
    0.3116384-1.1607067 0.6032788
    0.23685780.80313811.4902807
    -0.5188344 0.3066750 0.8187651
    -0.01050835-1.49125738 1.67045716
    -0.1782367 0.5089734-1.1149944
    1.0012814 0.7045562-0.2383923
    \n", "
  3. \n", "
\n" ], "text/latex": [ "\\begin{enumerate}\n", "\\item \\begin{enumerate*}\n", "\\item 1\n", "\\item 2\n", "\\item 3\n", "\\item 4\n", "\\item 5\n", "\\item 6\n", "\\item 7\n", "\\item 8\n", "\\item 9\n", "\\item 10\n", "\\end{enumerate*}\n", "\n", "\\item \\begin{tabular}{lll}\n", "\t -1.88415809 & -0.09135793 & -0.04933136\\\\\n", "\t 0.27581447 & 0.59928155 & -0.01019772\\\\\n", "\t 0.2350933 & -1.3818212 & -1.4915053\\\\\n", "\t -1.2959223 & -0.1018049 & -1.6248156\\\\\n", "\t 0.3116384 & -1.1607067 & 0.6032788\\\\\n", "\t 0.2368578 & 0.8031381 & 1.4902807\\\\\n", "\t -0.5188344 & 0.3066750 & 0.8187651\\\\\n", "\t -0.01050835 & -1.49125738 & 1.67045716\\\\\n", "\t -0.1782367 & 0.5089734 & -1.1149944\\\\\n", "\t 1.0012814 & 0.7045562 & -0.2383923\\\\\n", "\\end{tabular}\n", "\n", "\\end{enumerate}\n" ], "text/markdown": [ "1. 1. 1\n", "2. 2\n", "3. 3\n", "4. 4\n", "5. 5\n", "6. 6\n", "7. 7\n", "8. 8\n", "9. 9\n", "10. 10\n", "\n", "\n", "\n", "2. 1. -1.88415809010852\n", "2. 0.275814473843591\n", "3. 0.235093252207672\n", "4. -1.2959223421758\n", "5. 0.31163837633309\n", "6. 0.236857802627088\n", "7. -0.51883440659887\n", "8. -0.0105083520578843\n", "9. -0.178236742330678\n", "10. 1.00128144396921\n", "11. -0.0913579344345197\n", "12. 0.599281548671024\n", "13. -1.38182122043006\n", "14. -0.101804873202288\n", "15. -1.16070666357178\n", "16. 0.803138127712042\n", "17. 0.3066749718582\n", "18. -1.49125737985107\n", "19. 0.508973383650242\n", "20. 0.704556160593126\n", "21. -0.0493313617379338\n", "22. -0.0101977203214555\n", "23. -1.49150529746769\n", "24. -1.62481563262781\n", "25. 0.603278782840875\n", "26. 1.49028074842061\n", "27. 0.818765051852373\n", "28. 1.67045715534238\n", "29. -1.11499439496249\n", "30. -0.238392287857492\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "[[1]]\n", " [1] 1 2 3 4 5 6 7 8 9 10\n", "\n", "[[2]]\n", " [,1] [,2] [,3]\n", " [1,] -1.88415809 -0.09135793 -0.04933136\n", " [2,] 0.27581447 0.59928155 -0.01019772\n", " [3,] 0.23509325 -1.38182122 -1.49150530\n", " [4,] -1.29592234 -0.10180487 -1.62481563\n", " [5,] 0.31163838 -1.16070666 0.60327878\n", " [6,] 0.23685780 0.80313813 1.49028075\n", " [7,] -0.51883441 0.30667497 0.81876505\n", " [8,] -0.01050835 -1.49125738 1.67045716\n", " [9,] -0.17823674 0.50897338 -1.11499439\n", "[10,] 1.00128144 0.70455616 -0.23839229\n" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my.list<-list(v,m)\n", "my.list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, `my.list` contains a vector AND a matrix. Now, lets use `lapply`:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
    \n", "\t
    1. \n", "\t
    2. 2
    3. \n", "\t
    4. 4
    5. \n", "\t
    6. 6
    7. \n", "\t
    8. 8
    9. \n", "\t
    10. 10
    11. \n", "\t
    12. 12
    13. \n", "\t
    14. 14
    15. \n", "\t
    16. 16
    17. \n", "\t
    18. 18
    19. \n", "\t
    20. 20
    21. \n", "
    \n", "
  1. \n", "\t
  2. \n", "\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\n", "
    -3.76831618-0.18271587-0.09866272
    0.55162895 1.19856310-0.02039544
    0.4701865-2.7636424-2.9830106
    -2.5918447-0.2036097-3.2496313
    0.6232768-2.3214133 1.2065576
    0.47371561.60627632.9805615
    -1.0376688 0.6133499 1.6375301
    -0.0210167-2.9825148 3.3409143
    -0.3564735 1.0179468-2.2299888
    2.0025629 1.4091123-0.4767846
    \n", "
  3. \n", "
\n" ], "text/latex": [ "\\begin{enumerate}\n", "\\item \\begin{enumerate*}\n", "\\item 2\n", "\\item 4\n", "\\item 6\n", "\\item 8\n", "\\item 10\n", "\\item 12\n", "\\item 14\n", "\\item 16\n", "\\item 18\n", "\\item 20\n", "\\end{enumerate*}\n", "\n", "\\item \\begin{tabular}{lll}\n", "\t -3.76831618 & -0.18271587 & -0.09866272\\\\\n", "\t 0.55162895 & 1.19856310 & -0.02039544\\\\\n", "\t 0.4701865 & -2.7636424 & -2.9830106\\\\\n", "\t -2.5918447 & -0.2036097 & -3.2496313\\\\\n", "\t 0.6232768 & -2.3214133 & 1.2065576\\\\\n", "\t 0.4737156 & 1.6062763 & 2.9805615\\\\\n", "\t -1.0376688 & 0.6133499 & 1.6375301\\\\\n", "\t -0.0210167 & -2.9825148 & 3.3409143\\\\\n", "\t -0.3564735 & 1.0179468 & -2.2299888\\\\\n", "\t 2.0025629 & 1.4091123 & -0.4767846\\\\\n", "\\end{tabular}\n", "\n", "\\end{enumerate}\n" ], "text/markdown": [ "1. 1. 2\n", "2. 4\n", "3. 6\n", "4. 8\n", "5. 10\n", "6. 12\n", "7. 14\n", "8. 16\n", "9. 18\n", "10. 20\n", "\n", "\n", "\n", "2. 1. -3.76831618021705\n", "2. 0.551628947687182\n", "3. 0.470186504415344\n", "4. -2.5918446843516\n", "5. 0.623276752666179\n", "6. 0.473715605254176\n", "7. -1.03766881319774\n", "8. -0.0210167041157686\n", "9. -0.356473484661357\n", "10. 2.00256288793843\n", "11. -0.182715868869039\n", "12. 1.19856309734205\n", "13. -2.76364244086012\n", "14. -0.203609746404577\n", "15. -2.32141332714355\n", "16. 1.60627625542408\n", "17. 0.6133499437164\n", "18. -2.98251475970214\n", "19. 1.01794676730048\n", "20. 1.40911232118625\n", "21. -0.0986627234758675\n", "22. -0.020395440642911\n", "23. -2.98301059493538\n", "24. -3.24963126525562\n", "25. 1.20655756568175\n", "26. 2.98056149684122\n", "27. 1.63753010370475\n", "28. 3.34091431068476\n", "29. -2.22998878992498\n", "30. -0.476784575714984\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "[[1]]\n", " [1] 2 4 6 8 10 12 14 16 18 20\n", "\n", "[[2]]\n", " [,1] [,2] [,3]\n", " [1,] -3.7683162 -0.1827159 -0.09866272\n", " [2,] 0.5516289 1.1985631 -0.02039544\n", " [3,] 0.4701865 -2.7636424 -2.98301059\n", " [4,] -2.5918447 -0.2036097 -3.24963127\n", " [5,] 0.6232768 -2.3214133 1.20655757\n", " [6,] 0.4737156 1.6062763 2.98056150\n", " [7,] -1.0376688 0.6133499 1.63753010\n", " [8,] -0.0210167 -2.9825148 3.34091431\n", " [9,] -0.3564735 1.0179468 -2.22998879\n", "[10,] 2.0025629 1.4091123 -0.47678458\n" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lapply(my.list,function(x) x*2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What does `sapply` do?" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
    \n", "\t
    1. \n", "\t
    2. 2
    3. \n", "\t
    4. 4
    5. \n", "\t
    6. 6
    7. \n", "\t
    8. 8
    9. \n", "\t
    10. 10
    11. \n", "\t
    12. 12
    13. \n", "\t
    14. 14
    15. \n", "\t
    16. 16
    17. \n", "\t
    18. 18
    19. \n", "\t
    20. 20
    21. \n", "
    \n", "
  1. \n", "\t
  2. \n", "\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\n", "
    -3.76831618-0.18271587-0.09866272
    0.55162895 1.19856310-0.02039544
    0.4701865-2.7636424-2.9830106
    -2.5918447-0.2036097-3.2496313
    0.6232768-2.3214133 1.2065576
    0.47371561.60627632.9805615
    -1.0376688 0.6133499 1.6375301
    -0.0210167-2.9825148 3.3409143
    -0.3564735 1.0179468-2.2299888
    2.0025629 1.4091123-0.4767846
    \n", "
  3. \n", "
\n" ], "text/latex": [ "\\begin{enumerate}\n", "\\item \\begin{enumerate*}\n", "\\item 2\n", "\\item 4\n", "\\item 6\n", "\\item 8\n", "\\item 10\n", "\\item 12\n", "\\item 14\n", "\\item 16\n", "\\item 18\n", "\\item 20\n", "\\end{enumerate*}\n", "\n", "\\item \\begin{tabular}{lll}\n", "\t -3.76831618 & -0.18271587 & -0.09866272\\\\\n", "\t 0.55162895 & 1.19856310 & -0.02039544\\\\\n", "\t 0.4701865 & -2.7636424 & -2.9830106\\\\\n", "\t -2.5918447 & -0.2036097 & -3.2496313\\\\\n", "\t 0.6232768 & -2.3214133 & 1.2065576\\\\\n", "\t 0.4737156 & 1.6062763 & 2.9805615\\\\\n", "\t -1.0376688 & 0.6133499 & 1.6375301\\\\\n", "\t -0.0210167 & -2.9825148 & 3.3409143\\\\\n", "\t -0.3564735 & 1.0179468 & -2.2299888\\\\\n", "\t 2.0025629 & 1.4091123 & -0.4767846\\\\\n", "\\end{tabular}\n", "\n", "\\end{enumerate}\n" ], "text/markdown": [ "1. 1. 2\n", "2. 4\n", "3. 6\n", "4. 8\n", "5. 10\n", "6. 12\n", "7. 14\n", "8. 16\n", "9. 18\n", "10. 20\n", "\n", "\n", "\n", "2. 1. -3.76831618021705\n", "2. 0.551628947687182\n", "3. 0.470186504415344\n", "4. -2.5918446843516\n", "5. 0.623276752666179\n", "6. 0.473715605254176\n", "7. -1.03766881319774\n", "8. -0.0210167041157686\n", "9. -0.356473484661357\n", "10. 2.00256288793843\n", "11. -0.182715868869039\n", "12. 1.19856309734205\n", "13. -2.76364244086012\n", "14. -0.203609746404577\n", "15. -2.32141332714355\n", "16. 1.60627625542408\n", "17. 0.6133499437164\n", "18. -2.98251475970214\n", "19. 1.01794676730048\n", "20. 1.40911232118625\n", "21. -0.0986627234758675\n", "22. -0.020395440642911\n", "23. -2.98301059493538\n", "24. -3.24963126525562\n", "25. 1.20655756568175\n", "26. 2.98056149684122\n", "27. 1.63753010370475\n", "28. 3.34091431068476\n", "29. -2.22998878992498\n", "30. -0.476784575714984\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "[[1]]\n", " [1] 2 4 6 8 10 12 14 16 18 20\n", "\n", "[[2]]\n", " [,1] [,2] [,3]\n", " [1,] -3.7683162 -0.1827159 -0.09866272\n", " [2,] 0.5516289 1.1985631 -0.02039544\n", " [3,] 0.4701865 -2.7636424 -2.98301059\n", " [4,] -2.5918447 -0.2036097 -3.24963127\n", " [5,] 0.6232768 -2.3214133 1.20655757\n", " [6,] 0.4737156 1.6062763 2.98056150\n", " [7,] -1.0376688 0.6133499 1.63753010\n", " [8,] -0.0210167 -2.9825148 3.34091431\n", " [9,] -0.3564735 1.0179468 -2.22998879\n", "[10,] 2.0025629 1.4091123 -0.47678458\n" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sapply(my.list,function(x) x*2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Same thing! Well, what we see here is that R is sometimes smarter than us. `sapply` returns a list, because we gave it a list. Let's try something else:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " [,1]\n", "[1,] 2\n", "[2,] 4\n", "[3,] 6\n", "[4,] 8\n", "[5,] 10\n" ] } ], "source": [ "another.list<-list(1:5)\n", "mult.list<-sapply(another.list,function(x) x*2)\n", "print(mult.list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now what? `sapply` gave us a *matrix*. " ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
    \n", "\t
  1. 5
  2. \n", "\t
  3. 1
  4. \n", "
\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 5\n", "\\item 1\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 5\n", "2. 1\n", "\n", "\n" ], "text/plain": [ "[1] 5 1" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dim(mult.list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Why R does this is a bit beyond our scope. The take-away here is to be careful with data types, and try to give R the right one. If you want a vector returned, give R a vector, not a list!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### One more thing about lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you mix character or logical types, you can get unintended results:" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1]]\n", "[1] 2 4 6 8 10\n", "\n", "[[2]]\n", "[1] 2\n", "\n", "[[3]]\n", "[1] 2\n", "\n" ] } ], "source": [ "my.list<-list(1:5,TRUE,TRUE)\n", "mult.list<-sapply(my.list,function(x) x*2)\n", "print(mult.list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "R interpreted `TRUE` as a numeric 1." ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ERROR", "evalue": "Error in x * 2: non-numeric argument to binary operator\n", "output_type": "error", "traceback": [ "Error in x * 2: non-numeric argument to binary operator\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " [,1]\n", "[1,] 2\n", "[2,] 4\n", "[3,] 6\n", "[4,] 8\n", "[5,] 10\n" ] } ], "source": [ "my.list<-list(1:5,\"a\",\"b\")\n", "mult.list<-sapply(my.list,function(x) x*2)\n", "print(mult.list)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ERROR", "evalue": "Error in x * 2: non-numeric argument to binary operator\n", "output_type": "error", "traceback": [ "Error in x * 2: non-numeric argument to binary operator\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " [,1]\n", "[1,] 2\n", "[2,] 4\n", "[3,] 6\n", "[4,] 8\n", "[5,] 10\n" ] } ], "source": [ "my.list<-list(1:5,\"1\",\"2\")\n", "mult.list<-sapply(my.list,function(x) x*2)\n", "print(mult.list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In these last two examples, R returns an error, because we have tried to multiply by a character type." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "R", "language": "R", "name": "ir" }, "language_info": { "codemirror_mode": "r", "file_extension": ".r", "mimetype": "text/x-r-source", "name": "R", "pygments_lexer": "r", "version": "3.1.2" } }, "nbformat": 4, "nbformat_minor": 0 }