1176 lines
651 KiB
HTML
Raw Normal View History

2025-01-12 00:52:51 +08:00
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
<title>An Overview of the S4Vectors package</title>
<script>/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e
</script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(data:application/vnd.ms-fontobject;base64,n04AAEFNAAACAAIABAAAAAAABQAAAAAAAAABAJABAAAEAExQAAAAAAAAAAIAAAAAAAAAAAEAAAAAAAAAJxJ/LAAAAAAAAAAAAAAAAAAAAAAAACgARwBMAFkAUABIAEkAQwBPAE4AUwAgAEgAYQBsAGYAbABpAG4AZwBzAAAADgBSAGUAZwB1AGwAYQByAAAAeABWAGUAcgBzAGkAbwBuACAAMQAuADAAMAA5ADsAUABTACAAMAAwADEALgAwADAAOQA7AGgAbwB0AGMAbwBuAHYAIAAxAC4AMAAuADcAMAA7AG0AYQBrAGUAbwB0AGYALgBsAGkAYgAyAC4ANQAuADUAOAAzADIAOQAAADgARwBMAFkAUABIAEkAQwBPAE4AUwAgAEgAYQBsAGYAbABpAG4AZwBzACAAUgBlAGcAdQBsAGEAcgAAAAAAQlNHUAAAAAAAAAAAAAAAAAAAAAADAKncAE0TAE0ZAEbuFM3pjM/SEdmjKHUbyow8ATBE40IvWA3vTu8LiABDQ+pexwUMcm1SMnNryctQSiI1K5ZnbOlXKmnVV5YvRe6RnNMFNCOs1KNVpn6yZhCJkRtVRNzEufeIq7HgSrcx4S8h/v4vnrrKc6oCNxmSk2uKlZQHBii6iKFoH0746ThvkO1kJHlxjrkxs+LWORaDQBEtiYJIR5IB9Bi1UyL4Rmr0BNigNkMzlKQmnofBHviqVzUxwdMb3NdCn69hy+pRYVKGVS/1tnsqv4LL7wCCPZZAZPT4aCShHjHJVNuXbmMrY5LeQaGnvAkXlVrJgKRAUdFjrWEah9XebPeQMj7KS7DIBAFt8ycgC5PLGUOHSE3ErGZCiViNLL5ZARfywnCoZaKQCu6NuFX42AEeKtKUGnr/Cm2Cy8tpFhBPMW5Fxi4Qm4TkDWh4IWFDClhU2hRWosUWqcKLlgyXB+lSHaWaHiWlBAR8SeSgSPCQxdVQgzUixWKSTrIQEbU94viDctkvX+VSjJuUmV8L4CXShI11esnp0pjWNZIyxKHS4wVQ2ime1P4RnhvGw0aDN1OLAXGERsB7buFpFGGBAre4QEQR0HOIO5oYH305G+KspT/FupEGGafCCwxSe6ZUa+073rXHnNdVXE6eW
</style>
<script>/*!
* Bootstrap v3.3.5 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Licensed under the MIT license
*/
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==type
d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.5",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affi
<script>/**
* @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
// Only run this code in IE 8
if (!!window.navigator.userAgent.match("MSIE 8")) {
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document);
};
</script>
<script>/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
* Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
* */
// Only run this code in IE 8
if (!!window.navigator.userAgent.match("MSIE 8")) {
!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmVal
};
</script>
<style>h1 {font-size: 34px;}
h1.title {font-size: 38px;}
h2 {font-size: 30px;}
h3 {font-size: 24px;}
h4 {font-size: 18px;}
h5 {font-size: 16px;}
h6 {font-size: 12px;}
code {color: inherit; background-color: rgba(0, 0, 0, 0.04);}
</style>
<script>
/**
* jQuery Plugin: Sticky Tabs
*
* @author Aidan Lister <aidan@php.net>
* adapted by Ruben Arslan to activate parent tabs too
* http://www.aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/
*/
(function($) {
"use strict";
$.fn.rmarkdownStickyTabs = function() {
var context = this;
// Show the tab corresponding with the hash in the URL, or the first tab
var showStuffFromHash = function() {
var hash = window.location.hash;
var selector = hash ? 'a[href="' + hash + '"]' : 'li.active > a';
var $selector = $(selector, context);
if($selector.data('toggle') === "tab") {
$selector.tab('show');
// walk up the ancestors of this element, show any hidden tabs
$selector.parents('.section.tabset').each(function(i, elm) {
var link = $('a[href="#' + $(elm).attr('id') + '"]');
if(link.data('toggle') === "tab") {
link.tab("show");
}
});
}
};
// Set the correct tab when the page loads
showStuffFromHash(context);
// Set the correct tab when a user uses their back/forward button
$(window).on('hashchange', function() {
showStuffFromHash(context);
});
// Change the URL when tabs are clicked
$('a', context).on('click', function(e) {
history.pushState(null, null, this.href);
showStuffFromHash(context);
});
return this;
};
}(jQuery));
window.buildTabsets = function(tocID) {
// build a tabset from a section div with the .tabset class
function buildTabset(tabset) {
// check for fade and pills options
var fade = tabset.hasClass("tabset-fade");
var pills = tabset.hasClass("tabset-pills");
var navClass = pills ? "nav-pills" : "nav-tabs";
// determine the heading level of the tabset and tabs
var match = tabset.attr('class').match(/level(\d) /);
if (match === null)
return;
var tabsetLevel = Number(match[1]);
var tabLevel = tabsetLevel + 1;
// find all subheadings immediately below
var tabs = tabset.find("div.section.level" + tabLevel);
if (!tabs.length)
return;
// create tablist and tab-content elements
var tabList = $('<ul class="nav ' + navClass + '" role="tablist"></ul>');
$(tabs[0]).before(tabList);
var tabContent = $('<div class="tab-content"></div>');
$(tabs[0]).before(tabContent);
// build the tabset
var activeTab = 0;
tabs.each(function(i) {
// get the tab div
var tab = $(tabs[i]);
// get the id then sanitize it for use with bootstrap tabs
var id = tab.attr('id');
// see if this is marked as the active tab
if (tab.hasClass('active'))
activeTab = i;
// remove any table of contents entries associated with
// this ID (since we'll be removing the heading element)
$("div#" + tocID + " li a[href='#" + id + "']").parent().remove();
// sanitize the id for use with bootstrap tabs
id = id.replace(/[.\/?&!#<>]/g, '').replace(/\s/g, '_');
tab.attr('id', id);
// get the heading element within it, grab it's text, then remove it
var heading = tab.find('h' + tabLevel + ':first');
var headingText = heading.html();
heading.remove();
// build and append the tab list item
var a = $('<a role="tab" data-toggle="tab">' + headingText + '</a>');
a.attr('href', '#' + id);
a.attr('aria-controls', id);
var li = $('<li role="presentation"></li>');
li.append(a);
tabList.append(li);
// set it's attributes
tab.attr('role', 'tabpanel');
tab.addClass('tab-pane');
tab.addClass('tabbed-pane');
if (fade)
tab.addClass('fade');
// move it into the tab content div
tab.detach().appendTo(tabContent);
});
// set active tab
$(tabList.children('li')[activeTab]).addClass('active');
var active = $(tabContent.children('div.section')[activeTab]);
active.addClass('active');
if (fade)
active.addClass('in');
if (tabset.hasClass("tabset-sticky"))
tabset.rmarkdownStickyTabs();
}
// convert section divs with the .tabset class to tabsets
var tabsets = $("div.section.tabset");
tabsets.each(function(i) {
buildTabset($(tabsets[i]));
});
};
</script>
<style type="text/css">.hljs-literal {
color: #990073;
}
.hljs-number {
color: #099;
}
.hljs-comment {
color: #998;
font-style: italic;
}
.hljs-keyword {
color: #900;
font-weight: bold;
}
.hljs-string {
color: #d14;
}
</style>
<script src="data:application/javascript;base64,LyohIGhpZ2hsaWdodC5qcyB2OS4xMi4wIHwgQlNEMyBMaWNlbnNlIHwgZ2l0LmlvL2hsanNsaWNlbnNlICovCiFmdW5jdGlvbihlKXt2YXIgbj0ib2JqZWN0Ij09dHlwZW9mIHdpbmRvdyYmd2luZG93fHwib2JqZWN0Ij09dHlwZW9mIHNlbGYmJnNlbGY7InVuZGVmaW5lZCIhPXR5cGVvZiBleHBvcnRzP2UoZXhwb3J0cyk6biYmKG4uaGxqcz1lKHt9KSwiZnVuY3Rpb24iPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kJiZkZWZpbmUoW10sZnVuY3Rpb24oKXtyZXR1cm4gbi5obGpzfSkpfShmdW5jdGlvbihlKXtmdW5jdGlvbiBuKGUpe3JldHVybiBlLnJlcGxhY2UoLyYvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsiKS5yZXBsYWNlKC8+L2csIiZndDsiKX1mdW5jdGlvbiB0KGUpe3JldHVybiBlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gcihlLG4pe3ZhciB0PWUmJmUuZXhlYyhuKTtyZXR1cm4gdCYmMD09PXQuaW5kZXh9ZnVuY3Rpb24gYShlKXtyZXR1cm4gay50ZXN0KGUpfWZ1bmN0aW9uIGkoZSl7dmFyIG4sdCxyLGksbz1lLmNsYXNzTmFtZSsiICI7aWYobys9ZS5wYXJlbnROb2RlP2UucGFyZW50Tm9kZS5jbGFzc05hbWU6IiIsdD1CLmV4ZWMobykpcmV0dXJuIHcodFsxXSk/dFsxXToibm8taGlnaGxpZ2h0Ijtmb3Iobz1vLnNwbGl0KC9ccysvKSxuPTAscj1vLmxlbmd0aDtyPm47bisrKWlmKGk9b1tuXSxhKGkpfHx3KGkpKXJldHVybiBpfWZ1bmN0aW9uIG8oZSl7dmFyIG4sdD17fSxyPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtmb3IobiBpbiBlKXRbbl09ZVtuXTtyZXR1cm4gci5mb3JFYWNoKGZ1bmN0aW9uKGUpe2ZvcihuIGluIGUpdFtuXT1lW25dfSksdH1mdW5jdGlvbiB1KGUpe3ZhciBuPVtdO3JldHVybiBmdW5jdGlvbiByKGUsYSl7Zm9yKHZhciBpPWUuZmlyc3RDaGlsZDtpO2k9aS5uZXh0U2libGluZykzPT09aS5ub2RlVHlwZT9hKz1pLm5vZGVWYWx1ZS5sZW5ndGg6MT09PWkubm9kZVR5cGUmJihuLnB1c2goe2V2ZW50OiJzdGFydCIsb2Zmc2V0OmEsbm9kZTppfSksYT1yKGksYSksdChpKS5tYXRjaCgvYnJ8aHJ8aW1nfGlucHV0Lyl8fG4ucHVzaCh7ZXZlbnQ6InN0b3AiLG9mZnNldDphLG5vZGU6aX0pKTtyZXR1cm4gYX0oZSwwKSxufWZ1bmN0aW9uIGMoZSxyLGEpe2Z1bmN0aW9uIGkoKXtyZXR1cm4gZS5sZW5ndGgmJnIubGVuZ3RoP2VbMF0ub2Zmc2V0IT09clswXS5vZmZzZXQ/ZVswXS5vZmZzZXQ8clswXS5vZmZzZXQ/ZTpyOiJzdGFydCI9PT1yWzBdLmV2ZW50P2U6cjplLmxlbmd0aD9lOnJ9ZnVuY3Rpb24gbyhlKXtmdW5jdGlvbiByKGUpe3JldHVybiIgIitlLm5vZGVOYW1lKyc9IicrbihlLnZhbHVlKS5yZXBsYWNlKCciJywiJnF1b3Q7IikrJyInfXMrPSI8Iit0KGUpK0UubWFwLmNhbGwoZS5hdHRyaWJ1dGVzLHIpLmpvaW4oIiIpKyI+In1mdW5jdGlvbiB1KGUpe3MrPSI8LyIrdChlKSsiPiJ9ZnVuY3Rpb24gYyhlKXsoInN0YXJ0Ij09PWUuZXZlbnQ/bzp1KShlLm5vZGUpfWZvcih2YXIgbD0wLHM9IiIsZj1bXTtlLmxlbmd0aHx8ci5sZW5ndGg7KXt2YXIgZz1pKCk7aWYocys9bihhLnN1YnN0cmluZyhsLGdbMF0ub2Zmc2V0KSksbD1nWzBdLm9mZnNldCxnPT09ZSl7Zi5yZXZlcnNlKCkuZm9yRWFjaCh1KTtkbyBjKGcuc3BsaWNlKDAsMSlbMF0pLGc9aSgpO3doaWxlKGc9PT1lJiZnLmxlbmd0aCYmZ1swXS5vZmZzZXQ9PT1sKTtmLnJldmVyc2UoKS5mb3JFYWNoKG8pfWVsc2Uic3RhcnQiPT09Z1swXS5ldmVudD9mLnB1c2goZ1swXS5ub2RlKTpmLnBvcCgpLGMoZy5zcGxpY2UoMCwxKVswXSl9cmV0dXJuIHMrbihhLnN1YnN0cihsKSl9ZnVuY3Rpb24gbChlKXtyZXR1cm4gZS52JiYhZS5jYWNoZWRfdmFyaWFudHMmJihlLmNhY2hlZF92YXJpYW50cz1lLnYubWFwKGZ1bmN0aW9uKG4pe3JldHVybiBvKGUse3Y6bnVsbH0sbil9KSksZS5jYWNoZWRfdmFyaWFudHN8fGUuZVcmJltvKGUpXXx8W2VdfWZ1bmN0aW9uIHMoZSl7ZnVuY3Rpb24gbihlKXtyZXR1cm4gZSYmZS5zb3VyY2V8fGV9ZnVuY3Rpb24gdCh0LHIpe3JldHVybiBuZXcgUmVnRXhwKG4odCksIm0iKyhlLmNJPyJpIjoiIikrKHI/ImciOiIiKSl9ZnVuY3Rpb24gcihhLGkpe2lmKCFhLmNvbXBpbGVkKXtpZihhLmNvbXBpbGVkPSEwLGEuaz1hLmt8fGEuYkssYS5rKXt2YXIgbz17fSx1PWZ1bmN0aW9uKG4sdCl7ZS5jSSYmKHQ9dC50b0xvd2VyQ2FzZSgpKSx0LnNwbGl0KCIgIikuZm9yRWFjaChmdW5jdGlvbihlKXt2YXIgdD1lLnNwbGl0KCJ8Iik7b1t0WzBdXT1bbix0WzFdP051bWJlcih0WzFdKToxXX0pfTsic3RyaW5nIj09dHlwZW9mIGEuaz91KCJrZXl3b3JkIixhLmspOngoYS5rKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3UoZSxhLmtbZV0pfSksYS5rPW99YS5sUj10KGEubHx8L1x3Ky8sITApLGkmJihhLmJLJiYoYS5iPSJcXGIoIithLmJLLnNwbGl0KCIgIikuam9pbigifCIpKyIpXFxiIiksYS5ifHwoYS5iPS9cQnxcYi8pLGEuYlI9dChhLmIpLGEuZXx8YS5lV3x8KGEuZT0vXEJ8XGIvKSxhLmUmJihhLmVSPXQoYS5lKSksYS50RT1uKGEuZSl8fCIiLGEuZVcmJmkudEUmJihhLnRFKz0oYS5lPyJ8IjoiIikraS50RSkpLGEuaSYmKGEuaVI9dChhLmkpKSxudWxsPT1hLnImJihhLnI9MSksYS5jfHwoYS5jPVtdKSxhLmM9QXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSxhLmMubWFwKGZ1bmN0aW9uKGUpe3JldHVybiBsKCJzZWxmIj09PWU/YTplKX0pKSxhLmMuZm9yRWFjaChmdW5jdGlvbihlKXtyKGUsYSl9KSxhLnN0YXJ0cyYmcihhLnN0YXJ0cyxpKTt2YXIgYz1hLmMubWFwKGZ1bmN0aW9uKGUpe3JldHVybiBlLmJLPyJcXC4/KCIrZS5iKyIpXFwuPyI6ZS5ifSkuY29uY2F0KFthLnRFLGEuaV0pLm1hcChuKS5maWx0ZXIoQm9vbGVhbik7YS50PWMubGVuZ3RoP3QoYy5qb2luKCJ8IiksITApOntleGVjOmZ1bmN0aW9uKCl7cmV0dXJuIG51bGx9fX19cihlKX1mdW5jdGlvbiBmKGUsdCxhLGkpe2Z1bmN0aW9uIG8oZSxuKXt2YXIgdCxhO2Zvcih0PTAsYT1uLmMubGVuZ3RoO2E+dDt0Kys
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<style type="text/css">code{white-space: pre;}</style>
<script type="text/javascript">
if (window.hljs) {
hljs.configure({languages: []});
hljs.initHighlightingOnLoad();
if (document.readyState && document.readyState === "complete") {
window.setTimeout(function() { hljs.initHighlighting(); }, 0);
}
}
</script>
<style type="text/css">body {
margin: 0px auto;
max-width: 1134px;
font-family: sans-serif;
font-size: 10pt;
}
div#TOC ul {
padding: 0px 0px 0px 45px;
list-style: none;
background-image: none;
background-repeat: none;
background-position: 0;
font-size: 10pt;
font-family: Helvetica, Arial, sans-serif;
}
div#TOC > ul {
padding: 0px 150px 0px 65px;
font-size: 12pt;
}
div#TOC > ul > li {
padding: 5px 0px 0px 0px;
}
div#TOC ul ul {
font-size: 11pt;
}
div#TOC.tocify ul {
padding: 0px;
font-size: inherit;
font-family: inherit;
}
div#TOC.tocify li {
padding: 5px;
font-size: inherit;
font-family: inherit;
}
p, dl {
padding: 0px 150px 0px 65px;
text-align: justify;
}
p, img, table {
margin-top: 10px;
margin-bottom: 10px;
}
ol, ul {
padding: 0px 150px 0px 100px;
list-style: square;
}
li ol, li ul {
padding: 0px 0px 0px 35px;
}
li p {
padding: 0;
}
pre {
margin: 0em 150px 0.5em 0em;
padding: 0px 0px 0px 65px;
border: 0px none;
background-color: #f0f0f0;
white-space: pre;
overflow-x: auto;
font-size: 90%;
}
li pre {
margin: 0em 0px 0.5em -65px;
padding: 0px 0px 0px 65px;
}
pre code {
background-color: inherit;
display: block;
padding: 10px 10px 10px 0px;
white-space: pre;
overflow-x: inherit;
font-size: 100%;
}
pre code[class] {
background-color: inherit;
}
pre[class] code {
background-color: inherit;
}
tt, code, pre {
font-family: 'DejaVu Sans Mono', 'Droid Sans Mono', 'Lucida Console', Consolas, Monaco, monospace;
}
h1, h2, h3, h4, h5, h6 {
font-family: Helvetica, Arial, sans-serif;
margin: 1.2em 150px 0.6em 0em;
padding-left: 65px;
text-indent: -65px;
}
h1.title {
color: #87b13f;
line-height: 1.1em;
margin-top: 25px;
border-bottom: 0px;
}
h1 {
line-height: 1.4em;
border-bottom: 1px #1a81c2 solid;
}
h1, h2, h3 {
color: #1a81c2;
}
h1 {
font-size: 18.0pt;
}
h2 {
font-size: 14.5pt;
}
h3, h4 {
font-size: 12pt;
}
span.header-section-number {
float: left;
width: 65px;
}
p.author-name {
font-size: 14.5pt;
font-weight: bold;
font-style: italic;
text-align: left;
}
.date {
text-indent: 0px;
font-weight: bold;
}
.abstract, .package {
font-weight: bold;
}
code {
background-color: #f0f0f0;
color: #404040;
font-size: 90%;
}
.figure {
margin: 0em 0px 0.5em;
}
img {
max-width: 100%;
display: block;
padding: 0px 150px 0px 130px;
}
p > img {
padding-left: 65px;
padding-right: 0px;
}
td > img {
padding: 0px;
max-width: 100%;
display: inline;
}
img.smallfigure {
padding-left: 195px;
padding-right: 280px;
}
p > img.smallfigure {
padding-left: 130px;
padding-right: 130px;
}
img.widefigure {
padding-left: 65px;
padding-right: 85px;
margin-right: -65px;
}
p > img.widefigure {
padding-left: 0px;
padding-right: 0px;
margin-right: -65px;
}
p.caption, caption {
color: inherit;
font-size: 8pt;
}
p.caption {
padding-left: 130px;
padding-right: 85px;
margin-bottom: 20px;
}
caption {
padding: 0px;
margin-bottom: 10px;
min-width: 583;
}
span.caption-title {
color: #1a81c2;
font-weight: bold;
}
span.caption-label {
font-weight: bold;
}
table {
margin-left: 130px;
margin-right: 85px;
}
.table {
max-width: 518px;
}
dd {
margin-left: 65px;
margin-bottom: 10px;
}
.code-folding-btn {
position: relative;
margin-top: -26px;
top: 26px;
}
.col-md-12 {
min-height: 0px;
}
.sidenote {
float: right;
clear: right;
margin-right: -150px;
width: 130px;
margin-top: 0;
margin-bottom: 1rem;
font-size: 8pt;
line-height: 1.3;
vertical-align: baseline;
position: relative;
text-align: left;
}
.sidenote-number, .affil-mark {
position: relative;
vertical-align: super;
font-size: 7.5pt;
font-weight: normal;
font-style: normal;
line-height: normal;
}
code > span.kw { color: #E07020; }
code > span.dt { color: #404040; }
code > span.dv { color: #D02070; }
code > span.bn { color: #d14; }
code > span.fl { color: #D02070; }
code > span.ch { color: #40A040; }
code > span.st { color: #40A040; }
code > span.co { color: #808080; font-style: italic; }
code > span.ot { color: #2020F0; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #E07020; }
code > span.er { color: #FF0000; }
code > span.identifier { color: #404040; }
code > span.number { color: #D02070; }
code > span.string { color: #40A040; }
code > span.comment { color: #808080; font-style: italic; }
code > span.keyword { color: #2020F0; }
code > span.literal { color: #2020F0; }
code > span.operator { color: #000000;}
code > span.paren { color: #000000;}
.js-plotly-plot .plotly {
padding-left: 65px;
}
.references {
padding-right: 150px;
}
.margin-toggle {
display: none;
}
@media screen and (max-width: 991px) {
body {
padding-left: 0;
margin-left: 0;
margin-right: 0;
width: auto;
}
p {
padding-left: 0;
padding-right: 0;
}
.references { padding-right: 0;
}
h1, h2, h3, h4, h5, h6 {
width: 100%;
padding-left: 0;
text-indent: 0;
}
ul {
padding-left: 20px;
padding-right: 0;
}
li pre {
margin-left: -20px;
padding-left: 10px;
}
pre {
margin-right: 0;
padding-left: 10px;
}
pre code {
white-space: pre;
}
p img{
padding-left: 0;
}
.horizontal-scroll {
overflow-x: auto;
}
.table {
min-width: 100%;
margin: 0 0 0 0;
}
div.figure img {
padding: 0 0 0 0;
}
div.figure p.caption {
padding-left: 0;
padding-right: 0;
}
.sidenote {
float: unset;
margin-top: 1rem;
margin-right: 0;
margin-left: 10%;
width: 80%;
font-size: 8pt;
line-height: 1.3;
text-align: left;
display: none;
}
.sidenote-number{
display: none;
}
.margin-toggle {
display: inline;
position: relative;
vertical-align: super;
font-size: 7.5pt;
font-weight: normal;
font-style: normal;
line-height: normal;
color: #337ab7;
}
}
@media screen and (max-width: 767px) {
#TOC {
display: none;
}
}
</style>
<style type="text/css">
.main-container {
max-width: 828px;
margin-left: auto;
margin-right: auto;
}
img {
max-width:100%;
}
.tabbed-pane {
padding-top: 12px;
}
.html-widget {
margin-bottom: 20px;
}
button.code-folding-btn:focus {
outline: none;
}
summary {
display: list-item;
}
details > summary > p:only-child {
display: inline;
}
</style>
<!-- tabsets -->
<style type="text/css">
.tabset-dropdown > .nav-tabs {
display: inline-table;
max-height: 500px;
min-height: 44px;
overflow-y: auto;
border: 1px solid #ddd;
border-radius: 4px;
}
.tabset-dropdown > .nav-tabs > li.active:before, .tabset-dropdown > .nav-tabs.nav-tabs-open:before {
content: "\e259";
font-family: 'Glyphicons Halflings';
display: inline-block;
padding: 10px;
border-right: 1px solid #ddd;
}
.tabset-dropdown > .nav-tabs.nav-tabs-open > li.active:before {
content: "\e258";
font-family: 'Glyphicons Halflings';
border: none;
}
.tabset-dropdown > .nav-tabs > li.active {
display: block;
}
.tabset-dropdown > .nav-tabs > li > a,
.tabset-dropdown > .nav-tabs > li > a:focus,
.tabset-dropdown > .nav-tabs > li > a:hover {
border: none;
display: inline-block;
border-radius: 4px;
background-color: transparent;
}
.tabset-dropdown > .nav-tabs.nav-tabs-open > li {
display: block;
float: none;
}
.tabset-dropdown > .nav-tabs > li {
display: none;
}
</style>
<!-- code folding -->
<script>
function toggle_visibility(id1) {
var e = document.getElementById(id1);
e.style.display = ((e.style.display!="none") ? "none" : "block");
}
</script>
</head>
<body>
<div class="container-fluid main-container">
<div id="header">
<h1 class="title toc-ignore">An Overview of the S4Vectors package</h1>
<p class="author-name">Patrick Aboyoun, Michael Lawrence and Hervé Pagès</p>
<h4 class="date">Edited: April 2024; Compiled: October 30 , 2024</h4>
<h4 class="package">Package</h4>
<p>S4Vectors 0.44.0</p>
</div>
<h1>Contents</h1>
<div id="TOC">
<ul>
<li><a href="#introduction"><span class="toc-section-number">1</span> Introduction</a></li>
<li><a href="#vector-like-and-list-like-objects"><span class="toc-section-number">2</span> Vector-like and list-like objects</a><ul>
<li><a href="#vector-like-objects"><span class="toc-section-number">2.1</span> Vector-like objects</a><ul>
<li><a href="#subsetting-a-vector-like-object"><span class="toc-section-number">2.1.1</span> Subsetting a vector-like object</a></li>
<li><a href="#concatenating-vector-like-objects"><span class="toc-section-number">2.1.2</span> Concatenating vector-like objects</a></li>
<li><a href="#looping-over-subsequences-of-vector-like-objects"><span class="toc-section-number">2.1.3</span> Looping over subsequences of vector-like objects</a></li>
<li><a href="#more-on-rle-objects"><span class="toc-section-number">2.1.4</span> More on <em>Rle</em> objects</a></li>
</ul></li>
<li><a href="#list-like-objects"><span class="toc-section-number">2.2</span> List-like objects</a></li>
</ul></li>
<li><a href="#vector-annotations"><span class="toc-section-number">3</span> Vector Annotations</a></li>
<li><a href="#session-information"><span class="toc-section-number">4</span> Session Information</a></li>
</ul>
</div>
<div id="introduction" class="section level1">
<h1><span class="header-section-number">1</span> Introduction</h1>
<p>The <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> package provides a framework for representing
vector-like and list-like objects as S4 objects. It defines two central virtual
classes, <em>Vector</em> and <em>List</em>, and a set of generic functions that extend the
semantic of ordinary vectors and lists in <em>R</em>. Package developers can easily
implement vector-like or list-like objects as <em>Vector</em> and/or <em>List</em>
derivatives. A few low-level <em>Vector</em> and <em>List</em> derivatives are implemented in
the <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> package itself e.g. <em>Hits</em>, <em>Rle</em>, and
<em>DataFrame</em>). Many more are implemented in the <em><a href="https://bioconductor.org/packages/3.20/IRanges">IRanges</a></em> and
<em><a href="https://bioconductor.org/packages/3.20/GenomicRanges">GenomicRanges</a></em> infrastructure packages, and in many other
Bioconductor packages.</p>
<p>In this vignette, we will rely on simple, illustrative example datasets, rather
than large, real-world data, so that each data structure and algorithm can be
explained in an intuitive, graphical manner. We expect that packages that apply
<em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> to a particular problem domain will provide vignettes
with relevant, realistic examples.</p>
<p>The <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> package is available at bioconductor.org and can be
downloaded via <code>BiocManager::install</code>:</p>
<pre class="r"><code>if (!require(&quot;BiocManager&quot;))
install.packages(&quot;BiocManager&quot;)
BiocManager::install(&quot;S4Vectors&quot;) </code></pre>
<pre class="r"><code>library(S4Vectors)</code></pre>
</div>
<div id="vector-like-and-list-like-objects" class="section level1">
<h1><span class="header-section-number">2</span> Vector-like and list-like objects</h1>
<p>In the context of the <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> package, a vector-like object is
an ordered finite collection of elements. All vector-like objects have three
main properties: (1) a notion of length or number of elements, (2) the ability
to extract elements to create new vector-like objects, and (3) the ability to be
concatenated with one or more vector-like objects to form larger vector-like
objects. The main functions for these three operations are <code>length</code>, <code>[</code>, and
<code>c</code>. Supporting these operations provide a great deal of power and many
vector-like object manipulations can be constructed using them.</p>
<p>Some vector-like objects can also have a list-like semantic, which means that
individual elements can be extracted with <code>[[</code>.</p>
<p>In <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> and many other Bioconductor packages, vector-like
and list-like objects derive from the <em>Vector</em> and <em>List</em> virtual classes,
respectively. Note that <em>List</em> is a subclass of <em>Vector</em>.
The following subsections describe each in turn.</p>
<div id="vector-like-objects" class="section level2">
<h2><span class="header-section-number">2.1</span> Vector-like objects</h2>
<p>As a first example of vector-like objects, well look at <em>Rle</em> objects. In <em>R</em>,
atomic sequences are typically stored in atomic vectors. But there are times
when these object become too large to manage in memory. When there are lots of
consecutive repeats in the sequence, the data can be compressed and managed in
memory through a run-length encoding where a data value is paired with a run
length. For example, the sequence {1, 1, 1, 2, 3, 3} can be represented as
values = {1, 2, 3}, run lengths = {3, 1, 2}.</p>
<p>The <em>Rle</em> class defined in the <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> package is used to
represent a run-length encoded (compressed) sequence of <em>logical</em>, <em>integer</em>,
<em>numeric</em>, <em>complex</em>, <em>character</em>, <em>raw</em>, or <em>factor</em> values. Note that the
<em>Rle</em> class extends the <em>Vector</em> virtual class:</p>
<pre class="r"><code>showClass(&quot;Rle&quot;)</code></pre>
<pre><code>## Class &quot;Rle&quot; [package &quot;S4Vectors&quot;]
##
## Slots:
##
## Name: values lengths elementMetadata metadata
## Class: vector_OR_factor integer_OR_LLint DataFrame_OR_NULL list
##
## Extends:
## Class &quot;Vector&quot;, directly
## Class &quot;Annotated&quot;, by class &quot;Vector&quot;, distance 2
## Class &quot;vector_OR_Vector&quot;, by class &quot;Vector&quot;, distance 2</code></pre>
<p>One way to construct <em>Rle</em> objects is through the <em>Rle</em> constructor function:</p>
<pre class="r"><code>set.seed(0)
lambda &lt;- c(rep(0.001, 4500), seq(0.001, 10, length=500),
seq(10, 0.001, length=500))
xVector &lt;- rpois(1e7, lambda)
yVector &lt;- rpois(1e7, lambda[c(251:length(lambda), 1:250)])
xRle &lt;- Rle(xVector)
yRle &lt;- Rle(yVector)</code></pre>
<p><em>Rle</em> objects are vector-like objects:</p>
<pre class="r"><code>length(xRle)</code></pre>
<pre><code>## [1] 10000000</code></pre>
<pre class="r"><code>xRle[1]</code></pre>
<pre><code>## integer-Rle of length 1 with 1 run
## Lengths: 1
## Values : 0</code></pre>
<pre class="r"><code>zRle &lt;- c(xRle, yRle)</code></pre>
<div id="subsetting-a-vector-like-object" class="section level3">
<h3><span class="header-section-number">2.1.1</span> Subsetting a vector-like object</h3>
<p>As with ordinary <em>R</em> atomic vectors, it is often necessary to subset one
sequence from another. When this subsetting does not duplicate or reorder the
elements being extracted, the result is called a <em>subsequence</em>. In general, the
<code>[</code> function can be used to construct a new sequence or extract a subsequence,
but its interface is often inconvenient and not amenable to optimization. To
compensate for this, the <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> package supports seven
additional functions for sequence extraction:</p>
<p>1.<code>window</code> - Extracts a subsequence over a specified region.</p>
<p>2.<code>subset</code> - Extracts the subsequence specified by a logical vector.</p>
<p>3.<code>head</code> - Extracts a consecutive subsequence containing the first n
elements.</p>
<p>4.<code>tail</code> - Extracts a consecutive subsequence containing the last n
elements.</p>
<p>5.<code>rev</code> - Creates a new sequence with the elements in the reverse order.</p>
<p>6.<code>rep</code> - Creates a new sequence by repeating sequence elements.</p>
<p>The following code illustrates how these functions are used on an <em>Rle</em> vector:</p>
<pre class="r"><code>xSnippet &lt;- window(xRle, 4751, 4760)
xSnippet</code></pre>
<pre><code>## integer-Rle of length 10 with 9 runs
## Lengths: 1 1 1 1 1 1 1 1 2
## Values : 4 6 5 4 6 2 6 7 5</code></pre>
<pre class="r"><code>head(xSnippet)</code></pre>
<pre><code>## integer-Rle of length 6 with 6 runs
## Lengths: 1 1 1 1 1 1
## Values : 4 6 5 4 6 2</code></pre>
<pre class="r"><code>tail(xSnippet)</code></pre>
<pre><code>## integer-Rle of length 6 with 5 runs
## Lengths: 1 1 1 1 2
## Values : 6 2 6 7 5</code></pre>
<pre class="r"><code>rev(xSnippet)</code></pre>
<pre><code>## integer-Rle of length 10 with 9 runs
## Lengths: 2 1 1 1 1 1 1 1 1
## Values : 5 7 6 2 6 4 5 6 4</code></pre>
<pre class="r"><code>rep(xSnippet, 2)</code></pre>
<pre><code>## integer-Rle of length 20 with 18 runs
## Lengths: 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2
## Values : 4 6 5 4 6 2 6 7 5 4 6 5 4 6 2 6 7 5</code></pre>
<pre class="r"><code>subset(xSnippet, xSnippet &gt;= 5L)</code></pre>
<pre><code>## integer-Rle of length 7 with 5 runs
## Lengths: 1 1 2 1 2
## Values : 6 5 6 7 5</code></pre>
</div>
<div id="concatenating-vector-like-objects" class="section level3">
<h3><span class="header-section-number">2.1.2</span> Concatenating vector-like objects</h3>
<p>The <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> package uses two generic functions, <code>c</code> and
<code>append</code>, for concatenating two <em>Vector</em> derivatives. The methods for <em>Vector</em>
objects follow the definition that these two functions are given the
<em>base</em> package.</p>
<pre class="r"><code>c(xSnippet, rev(xSnippet))</code></pre>
<pre><code>## integer-Rle of length 20 with 17 runs
## Lengths: 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1
## Values : 4 6 5 4 6 2 6 7 5 7 6 2 6 4 5 6 4</code></pre>
<pre class="r"><code>append(xSnippet, xSnippet, after=3)</code></pre>
<pre><code>## integer-Rle of length 20 with 18 runs
## Lengths: 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 2
## Values : 4 6 5 4 6 5 4 6 2 6 7 5 4 6 2 6 7 5</code></pre>
</div>
<div id="looping-over-subsequences-of-vector-like-objects" class="section level3">
<h3><span class="header-section-number">2.1.3</span> Looping over subsequences of vector-like objects</h3>
<p>In <em>R</em>, <code>for</code> looping can be an expensive operation. To compensate for this, the
<em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> package provides <code>aggregate</code> and <code>shiftApply</code> methods
(<code>shiftApply</code> is a new generic function defined in <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> to
perform calculations over subsequences of vector-like objects.</p>
<p>The <code>aggregate</code> function combines sequence extraction functionality of the
<code>window</code> function with looping capabilities of the <code>sapply</code> function. For
example, here is some code to compute medians across a moving window of width 3
using the function <code>aggregate</code>:</p>
<pre class="r"><code>xSnippet</code></pre>
<pre><code>## integer-Rle of length 10 with 9 runs
## Lengths: 1 1 1 1 1 1 1 1 2
## Values : 4 6 5 4 6 2 6 7 5</code></pre>
<pre class="r"><code>aggregate(xSnippet, start=1:8, width=3, FUN=median)</code></pre>
<pre><code>## [1] 5 5 5 4 6 6 6 5</code></pre>
<p>The <code>shiftApply</code> function is a looping operation involving two vector-like
objects whose elements are lined up via a positional shift operation. For
example, the elements of <code>xRle</code> and <code>yRle</code> were simulated from Poisson
distributions with the mean of element i from <code>yRle</code> being equivalent to the
mean of element i + 250 from <code>xRle</code>. If we did not know the size of the shift,
we could estimate it by finding the shift that maximizes the correlation between
<code>xRle</code> and <code>yRle</code>.</p>
<pre class="r"><code>cor(xRle, yRle)</code></pre>
<pre><code>## [1] 0.5739224</code></pre>
<pre class="r"><code>shifts &lt;- seq(235, 265, by=3)
corrs &lt;- shiftApply(shifts, yRle, xRle, FUN=cor)</code></pre>
<pre class="r"><code>plot(shifts, corrs)</code></pre>
<div class="figure" style="text-align: center"><span style="display:block;" id="fig:figshiftcorrs"></span>
<img src="data:image/png;base64,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
<p class="caption">
Figure 1: <span class="caption-title">Correlation between <code>xRle</code> and <code>yRle</code> for various shifts</span><br>
</p>
</div>
<p>The result is shown in Fig.<a href="#fig:figshiftcorrs">1</a></p>
</div>
<div id="more-on-rle-objects" class="section level3">
<h3><span class="header-section-number">2.1.4</span> More on <em>Rle</em> objects</h3>
<p>When there are lots of consecutive repeats, the memory savings through an RLE
can be quite dramatic. For example, the <code>xRle</code> object occupies less than one
third of the space of the original <code>xVector</code> object, while storing the same
information:</p>
<pre class="r"><code>as.vector(object.size(xRle) / object.size(xVector))</code></pre>
<pre><code>## [1] 0.3020726</code></pre>
<pre class="r"><code>identical(as.vector(xRle), xVector)</code></pre>
<pre><code>## [1] TRUE</code></pre>
<p>The functions <code>runValue</code> and <code>runLength</code> extract the run values and run lengths
from an <em>Rle</em> object respectively:</p>
<pre class="r"><code>head(runValue(xRle))</code></pre>
<pre><code>## [1] 0 1 0 1 0 1</code></pre>
<pre class="r"><code>head(runLength(xRle))</code></pre>
<pre><code>## [1] 780 1 208 1 1599 1</code></pre>
<p>The <em>Rle</em> class supports many of the basic methods associated with <em>R</em> atomic
vectors including the Ops, Math, Math2, Summary, and Complex group generics.
Here is a example of manipulating <em>Rle</em> objects using methods from the Ops
group:</p>
<pre class="r"><code>xRle &gt; 0</code></pre>
<pre><code>## logical-Rle of length 10000000 with 197127 runs
## Lengths: 780 1 208 1 1599 ... 5 1 91 1 927
## Values : FALSE TRUE FALSE TRUE FALSE ... FALSE TRUE FALSE TRUE FALSE</code></pre>
<pre class="r"><code>xRle + yRle</code></pre>
<pre><code>## integer-Rle of length 10000000 with 1957707 runs
## Lengths: 780 1 208 1 13 1 413 1 ... 1 5 1 91 1 507 1 419
## Values : 0 1 0 1 0 1 0 1 ... 2 0 1 0 1 0 1 0</code></pre>
<pre class="r"><code>xRle &gt; 0 | yRle &gt; 0</code></pre>
<pre><code>## logical-Rle of length 10000000 with 210711 runs
## Lengths: 780 1 208 1 13 ... 91 1 507 1 419
## Values : FALSE TRUE FALSE TRUE FALSE ... FALSE TRUE FALSE TRUE FALSE</code></pre>
<p>Here are some from the Summary group:</p>
<pre class="r"><code>range(xRle)</code></pre>
<pre><code>## [1] 0 26</code></pre>
<pre class="r"><code>sum(xRle &gt; 0 | yRle &gt; 0)</code></pre>
<pre><code>## [1] 2105185</code></pre>
<p>And here is one from the Math group:</p>
<pre class="r"><code>log1p(xRle)</code></pre>
<pre><code>## numeric-Rle of length 10000000 with 1510219 runs
## Lengths: 780 1 208 1 ... 91 1 927
## Values : 0.000000 0.693147 0.000000 0.693147 ... 0.000000 0.693147 0.000000</code></pre>
<p>As with atomic vectors, the <code>cor</code> and <code>shiftApply</code> functions operate on <em>Rle</em>
objects:</p>
<pre class="r"><code>cor(xRle, yRle)</code></pre>
<pre><code>## [1] 0.5739224</code></pre>
<pre class="r"><code>shiftApply(249:251, yRle, xRle,
FUN=function(x, y) {var(x, y) / (sd(x) * sd(y))})</code></pre>
<pre><code>## [1] 0.8519138 0.8517324 0.8517725</code></pre>
<p>For more information on the methods supported by the <em>Rle</em> class, consult the
<code>Rle</code> man page.</p>
</div>
</div>
<div id="list-like-objects" class="section level2">
<h2><span class="header-section-number">2.2</span> List-like objects</h2>
<p>Just as with ordinary <em>R</em> <em>List</em> objects, <em>List</em>-derived objects support <code>[[</code>
for element extraction, <code>c</code> for concatenating, and <code>lapply</code>/<code>sapply</code> for
looping. <code>lapply</code> and <code>sapply</code> are familiar to many <em>R</em> users since they are the
standard functions for looping over the elements of an <em>R</em> <em>list</em> object.</p>
<p>In addition, the <em><a href="https://bioconductor.org/packages/3.20/S4Vectors">S4Vectors</a></em> package introduces the <code>endoapply</code>
function to perform an endomorphism equivalent to <code>lapply</code>, i.e. it returns a
<em>List</em> derivative of the same class as the input rather than a <em>list</em> object.</p>
<p>An example of <em>List</em> derivative is the <em>DataFrame</em> class:</p>
<pre class="r"><code>showClass(&quot;DataFrame&quot;)</code></pre>
<pre><code>## Virtual Class &quot;DataFrame&quot; [package &quot;S4Vectors&quot;]
##
## Slots:
##
## Name: elementType elementMetadata metadata
## Class: character DataFrame_OR_NULL list
##
## Extends:
## Class &quot;RectangularData&quot;, directly
## Class &quot;List&quot;, directly
## Class &quot;DataFrame_OR_NULL&quot;, directly
## Class &quot;Vector&quot;, by class &quot;List&quot;, distance 2
## Class &quot;list_OR_List&quot;, by class &quot;List&quot;, distance 2
## Class &quot;Annotated&quot;, by class &quot;List&quot;, distance 3
## Class &quot;vector_OR_Vector&quot;, by class &quot;List&quot;, distance 3
##
## Known Subclasses: &quot;DFrame&quot;</code></pre>
<p>One way to construct <em>DataFrame</em> objects is through the <em>DataFrame</em> constructor
function:</p>
<pre class="r"><code>df &lt;- DataFrame(x=xRle, y=yRle)
sapply(df, class)</code></pre>
<pre><code>## x y
## &quot;Rle&quot; &quot;Rle&quot;</code></pre>
<pre class="r"><code>sapply(df, summary)</code></pre>
<pre><code>## x y
## Min. 0.0000000 0.0000000
## 1st Qu. 0.0000000 0.0000000
## Median 0.0000000 0.0000000
## Mean 0.9090338 0.9096009
## 3rd Qu. 0.0000000 0.0000000
## Max. 26.0000000 27.0000000</code></pre>
<pre class="r"><code>sapply(as.data.frame(df), summary)</code></pre>
<pre><code>## x y
## Min. 0.0000000 0.0000000
## 1st Qu. 0.0000000 0.0000000
## Median 0.0000000 0.0000000
## Mean 0.9090338 0.9096009
## 3rd Qu. 0.0000000 0.0000000
## Max. 26.0000000 27.0000000</code></pre>
<pre class="r"><code>endoapply(df, `+`, 0.5)</code></pre>
<pre><code>## DataFrame with 10000000 rows and 2 columns
## x y
## &lt;Rle&gt; &lt;Rle&gt;
## 1 0.5 0.5
## 2 0.5 0.5
## 3 0.5 0.5
## 4 0.5 0.5
## 5 0.5 0.5
## ... ... ...
## 9999996 0.5 0.5
## 9999997 0.5 0.5
## 9999998 0.5 0.5
## 9999999 0.5 0.5
## 10000000 0.5 0.5</code></pre>
<p>For more information on <em>DataFrame</em> objects, consult the <em>DataFrame</em> man page.</p>
<p>See the &quot;An Overview of the <em><a href="https://bioconductor.org/packages/3.20/IRanges">IRanges</a></em> package vignette in the
<em><a href="https://bioconductor.org/packages/3.20/IRanges">IRanges</a></em> package for many more examples of <em>List</em> derivatives.</p>
</div>
</div>
<div id="vector-annotations" class="section level1">
<h1><span class="header-section-number">3</span> Vector Annotations</h1>
<p>Often when one has a collection of objects, there is a need to attach metadata
that describes the collection in some way. Two kinds of metadata can be attached
to a <em>Vector</em> object:</p>
<ol style="list-style-type: decimal">
<li>Metadata about the object as a whole: this metadata is accessed via
the <code>metadata</code> accessor and is represented as an ordinary <em>list</em>;</li>
<li>Metadata about the individual elements of the object: this metadata
is accessed via the <code>mcols</code> accessor (<code>mcols</code> stands for <em>metadata
columns</em>) and is represented as a <em>DataFrame</em> object.This
<em>DataFrame</em> object can be thought of as the result of binding
together one or several vector-like objects (the metadata columns)
of the same length as the <em>Vector</em> object. Each row of the
<em>DataFrame</em> object annotates the corresponding element of the
<em>Vector</em> object.</li>
</ol>
</div>
<div id="session-information" class="section level1">
<h1><span class="header-section-number">4</span> Session Information</h1>
<p>Here is the output of <code>sessionInfo()</code> on the system on which this document was
compiled:</p>
<pre><code>## R version 4.4.1 (2024-06-14 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows Server 2022 x64 (build 20348)
##
## Matrix products: default
##
##
## locale:
## [1] LC_COLLATE=C
## [2] LC_CTYPE=English_United States.utf8
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C
## [5] LC_TIME=English_United States.utf8
##
## time zone: America/New_York
## tzcode source: internal
##
## attached base packages:
## [1] stats4 stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] S4Vectors_0.44.0 BiocGenerics_0.52.0 BiocStyle_2.34.0
##
## loaded via a namespace (and not attached):
## [1] cli_3.6.3 knitr_1.48 rlang_1.1.4
## [4] magick_2.8.5 xfun_0.48 highr_0.11
## [7] jsonlite_1.8.9 htmltools_0.5.8.1 tinytex_0.53
## [10] sass_0.4.9 rmarkdown_2.28 evaluate_1.0.1
## [13] jquerylib_0.1.4 fastmap_1.2.0 IRanges_2.40.0
## [16] yaml_2.3.10 lifecycle_1.0.4 bookdown_0.41
## [19] BiocManager_1.30.25 compiler_4.4.1 Rcpp_1.0.13
## [22] digest_0.6.37 R6_2.5.1 magrittr_2.0.3
## [25] bslib_0.8.0 tools_4.4.1 cachem_1.1.0</code></pre>
</div>
</div>
<script>
// add bootstrap table styles to pandoc tables
function bootstrapStylePandocTables() {
$('tr.odd').parent('tbody').parent('table').addClass('table table-condensed');
}
$(document).ready(function () {
bootstrapStylePandocTables();
});
</script>
<!-- tabsets -->
<script>
$(document).ready(function () {
window.buildTabsets("TOC");
});
$(document).ready(function () {
$('.tabset-dropdown > .nav-tabs > li').click(function () {
$(this).parent().toggleClass('nav-tabs-open');
});
});
</script>
<!-- code folding -->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
"HTML-CSS": {
styles: {
".MathJax_Display": {
"text-align": "center",
padding: "0px 150px 0px 65px",
margin: "0px 0px 0.5em"
},
"@media screen and (max-width: 991px)": {
".MathJax_Display": {
"text-align": "center",
padding: "0 0 0 0"
}
}
}
}
});
</script>
<!-- dynamically load mathjax for compatibility with self-contained -->
<script>
(function () {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
document.getElementsByTagName("head")[0].appendChild(script);
})();
</script>
<script type="text/javascript">
$(document).ready(function () {
// Map "enter" keypress to the same action as a cursor click
function navigateLink(e) {
if (e.key === "Enter") {
$(this).trigger("click");
}
}
var toc_items = document.querySelectorAll(".tocify-item");
for (var i = 0; i < toc_items.length; i++) {
// The link role tells screen readers this is for navigation
toc_items.item(i).setAttribute("role", "link");
// tabindex = 0 allows selection via keyboard tab presses
toc_items.item(i).setAttribute("tabindex", "0");
// Listen for "Enter" keypress when item is selected
toc_items.item(i).addEventListener("keydown", navigateLink);
}
});
</script>
</body>
</html>