diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0c6713e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +# ignore everything +** + +# except what we need +!/pm25_iweek_startdate.csv +!/habre.tif +!/renv.lock +!/entrypoint.R diff --git a/.github/workflows/build-deploy-pr.yaml b/.github/workflows/build-deploy-pr.yaml new file mode 100644 index 0000000..927e08e --- /dev/null +++ b/.github/workflows/build-deploy-pr.yaml @@ -0,0 +1,40 @@ +name: build-deploy-pr +on: + pull_request: +jobs: + deploy-images: + runs-on: ubuntu-latest + env: + registry: ghcr.io + username: degauss-org + repository: habre_pm + strategy: + fail-fast: false + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: create latest tag variable + run: | + container="${{ env.registry }}/${{ env.username}}/${{ env.repository }}:latest" + echo "container=${container}" >> $GITHUB_ENV + - name: create pull request tag variable based on name of associated branch + if: github.event_name == 'pull_request' + run: | + versioned="${{ env.registry }}/${{ env.username}}/${{ env.repository }}:${GITHUB_HEAD_REF}" + echo "versioned=${versioned}" >> $GITHUB_ENV + - name: build container + run: | + docker build -t ${{ env.container }} . + - name: test run container + run: | + docker run --rm -v "${PWD}/test":/tmp ${{ env.container }} my_address_file_geocoded.csv + - name: login to ghcr + uses: docker/login-action@v1 + with: + registry: ${{ env.registry }} + username: ${{ env.username }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: deploy pull request container + run: | + docker tag ${{ env.container }} ${{ env.versioned }} + docker push ${{ env.versioned }} \ No newline at end of file diff --git a/.github/workflows/build-deploy-release.yaml b/.github/workflows/build-deploy-release.yaml new file mode 100644 index 0000000..5c572ae --- /dev/null +++ b/.github/workflows/build-deploy-release.yaml @@ -0,0 +1,42 @@ +name: build-deploy-release +on: + release: + types: [published] +jobs: + deploy-images: + runs-on: ubuntu-latest + env: + registry: ghcr.io + username: degauss-org + repository: habre_pm + strategy: + fail-fast: false + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: create latest tag variable + run: | + container="${{ env.registry }}/${{ env.username}}/${{ env.repository }}:latest" + echo "container=${container}" >> $GITHUB_ENV + - name: create release tag variable + if: github.event_name == 'release' + run: | + versioned="${{ env.registry }}/${{ env.username}}/${{ env.repository }}:${GITHUB_REF##*/}" + echo "versioned=${versioned}" >> $GITHUB_ENV + - name: build container + run: | + docker build -t ${{ env.container }} . + - name: test container + run: | + docker run --rm -v "${PWD}/test":/tmp ${{ env.container }} my_address_file_geocoded.csv + - name: login to ghcr + uses: docker/login-action@v1 + with: + registry: ${{ env.registry }} + username: ${{ env.username }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: deploy release (and latest) container + run: | + docker tag ${{ env.container }} ${{ env.versioned }} + docker push ${{ env.versioned }} + docker push ${{ env.container }} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b6a065 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.Rproj.user +.Rhistory +.RData +.Ruserdata diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..05254ee --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +FROM rocker/r-ver:4.2.2 + +# DeGAUSS container metadata +ENV degauss_name="habre_pm" +ENV degauss_version="0.1.0" +ENV degauss_description="weekly pm2.5 for California (Habre)" + +# add OCI labels based on environment variables too +LABEL "org.degauss.name"="${degauss_name}" +LABEL "org.degauss.version"="${degauss_version}" +LABEL "org.degauss.description"="${degauss_description}" + +RUN R --quiet -e "install.packages('remotes', repos = c(CRAN = 'https://packagemanager.rstudio.com/all/__linux__/focal/latest'))" + +RUN R --quiet -e "remotes::install_github('rstudio/renv@0.16.0')" + +WORKDIR /app + +RUN apt-get update \ + && apt-get install -yqq --no-install-recommends \ + libgdal-dev \ + libgeos-dev \ + libudunits2-dev \ + libproj-dev \ + && apt-get clean + +COPY renv.lock . + +RUN R --quiet -e "renv::restore()" + +COPY habre.tif . +COPY pm25_iweek_startdate.csv . +COPY entrypoint.R . + +WORKDIR /tmp + +ENTRYPOINT ["/app/entrypoint.R"] \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d2b2339 --- /dev/null +++ b/LICENSE @@ -0,0 +1,595 @@ +GNU General Public License +========================== + +_Version 3, 29 June 2007_ +_Copyright © 2007 Free Software Foundation, Inc. <>_ + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +## Preamble + +The GNU General Public License is a free, copyleft license for software and other +kinds of works. + +The licenses for most software and other practical works are designed to take away +your freedom to share and change the works. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change all versions of a +program--to make sure it remains free software for all its users. We, the Free +Software Foundation, use the GNU General Public License for most of our software; it +applies also to any other work released this way by its authors. You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General +Public Licenses are designed to make sure that you have the freedom to distribute +copies of free software (and charge for them if you wish), that you receive source +code or can get it if you want it, that you can change the software or use pieces of +it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or +asking you to surrender the rights. Therefore, you have certain responsibilities if +you distribute copies of the software, or if you modify it: responsibilities to +respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, +you must pass on to the recipients the same freedoms that you received. You must make +sure that they, too, receive or can get the source code. And you must show them these +terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: **(1)** assert +copyright on the software, and **(2)** offer you this License giving you legal permission +to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is +no warranty for this free software. For both users' and authors' sake, the GPL +requires that modified versions be marked as changed, so that their problems will not +be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of +the software inside them, although the manufacturer can do so. This is fundamentally +incompatible with the aim of protecting users' freedom to change the software. The +systematic pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we have designed +this version of the GPL to prohibit the practice for those products. If such problems +arise substantially in other domains, we stand ready to extend this provision to +those domains in future versions of the GPL, as needed to protect the freedom of +users. + +Finally, every program is threatened constantly by software patents. States should +not allow patents to restrict development and use of software on general-purpose +computers, but in those that do, we wish to avoid the special danger that patents +applied to a free program could make it effectively proprietary. To prevent this, the +GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +## TERMS AND CONDITIONS + +### 0. Definitions + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this +License. Each licensee is addressed as “you”. “Licensees” and +“recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in +a fashion requiring copyright permission, other than the making of an exact copy. The +resulting work is called a “modified version” of the earlier work or a +work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on +the Program. + +To “propagate” a work means to do anything with it that, without +permission, would make you directly or secondarily liable for infringement under +applicable copyright law, except executing it on a computer or modifying a private +copy. Propagation includes copying, distribution (with or without modification), +making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through a computer +network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the +extent that it includes a convenient and prominently visible feature that **(1)** +displays an appropriate copyright notice, and **(2)** tells the user that there is no +warranty for the work (except to the extent that warranties are provided), that +licensees may convey the work under this License, and how to view a copy of this +License. If the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + +### 1. Source Code + +The “source code” for a work means the preferred form of the work for +making modifications to it. “Object code” means any non-source form of a +work. + +A “Standard Interface” means an interface that either is an official +standard defined by a recognized standards body, or, in the case of interfaces +specified for a particular programming language, one that is widely used among +developers working in that language. + +The “System Libraries” of an executable work include anything, other than +the work as a whole, that **(a)** is included in the normal form of packaging a Major +Component, but which is not part of that Major Component, and **(b)** serves only to +enable use of the work with that Major Component, or to implement a Standard +Interface for which an implementation is available to the public in source code form. +A “Major Component”, in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system (if any) on which +the executable work runs, or a compiler used to produce the work, or an object code +interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the +source code needed to generate, install, and (for an executable work) run the object +code and to modify the work, including scripts to control those activities. However, +it does not include the work's System Libraries, or general-purpose tools or +generally available free programs which are used unmodified in performing those +activities but which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for the work, and +the source code for shared libraries and dynamically linked subprograms that the work +is specifically designed to require, such as by intimate data communication or +control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate +automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +### 2. Basic Permissions + +All rights granted under this License are granted for the term of copyright on the +Program, and are irrevocable provided the stated conditions are met. This License +explicitly affirms your unlimited permission to run the unmodified Program. The +output from running a covered work is covered by this License only if the output, +given its content, constitutes a covered work. This License acknowledges your rights +of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without +conditions so long as your license otherwise remains in force. You may convey covered +works to others for the sole purpose of having them make modifications exclusively +for you, or provide you with facilities for running those works, provided that you +comply with the terms of this License in conveying all material for which you do not +control copyright. Those thus making or running the covered works for you must do so +exclusively on your behalf, under your direction and control, on terms that prohibit +them from making any copies of your copyrighted material outside their relationship +with you. + +Conveying under any other circumstances is permitted solely under the conditions +stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +### 3. Protecting Users' Legal Rights From Anti-Circumvention Law + +No covered work shall be deemed part of an effective technological measure under any +applicable law fulfilling obligations under article 11 of the WIPO copyright treaty +adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention +of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of +technological measures to the extent such circumvention is effected by exercising +rights under this License with respect to the covered work, and you disclaim any +intention to limit operation or modification of the work as a means of enforcing, +against the work's users, your or third parties' legal rights to forbid circumvention +of technological measures. + +### 4. Conveying Verbatim Copies + +You may convey verbatim copies of the Program's source code as you receive it, in any +medium, provided that you conspicuously and appropriately publish on each copy an +appropriate copyright notice; keep intact all notices stating that this License and +any non-permissive terms added in accord with section 7 apply to the code; keep +intact all notices of the absence of any warranty; and give all recipients a copy of +this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer +support or warranty protection for a fee. + +### 5. Conveying Modified Source Versions + +You may convey a work based on the Program, or the modifications to produce it from +the Program, in the form of source code under the terms of section 4, provided that +you also meet all of these conditions: + +* **a)** The work must carry prominent notices stating that you modified it, and giving a +relevant date. +* **b)** The work must carry prominent notices stating that it is released under this +License and any conditions added under section 7. This requirement modifies the +requirement in section 4 to “keep intact all notices”. +* **c)** You must license the entire work, as a whole, under this License to anyone who +comes into possession of a copy. This License will therefore apply, along with any +applicable section 7 additional terms, to the whole of the work, and all its parts, +regardless of how they are packaged. This License gives no permission to license the +work in any other way, but it does not invalidate such permission if you have +separately received it. +* **d)** If the work has interactive user interfaces, each must display Appropriate Legal +Notices; however, if the Program has interactive interfaces that do not display +Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are +not by their nature extensions of the covered work, and which are not combined with +it such as to form a larger program, in or on a volume of a storage or distribution +medium, is called an “aggregate” if the compilation and its resulting +copyright are not used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work in an aggregate +does not cause this License to apply to the other parts of the aggregate. + +### 6. Conveying Non-Source Forms + +You may convey a covered work in object code form under the terms of sections 4 and +5, provided that you also convey the machine-readable Corresponding Source under the +terms of this License, in one of these ways: + +* **a)** Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by the Corresponding Source fixed on a +durable physical medium customarily used for software interchange. +* **b)** Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by a written offer, valid for at least +three years and valid for as long as you offer spare parts or customer support for +that product model, to give anyone who possesses the object code either **(1)** a copy of +the Corresponding Source for all the software in the product that is covered by this +License, on a durable physical medium customarily used for software interchange, for +a price no more than your reasonable cost of physically performing this conveying of +source, or **(2)** access to copy the Corresponding Source from a network server at no +charge. +* **c)** Convey individual copies of the object code with a copy of the written offer to +provide the Corresponding Source. This alternative is allowed only occasionally and +noncommercially, and only if you received the object code with such an offer, in +accord with subsection 6b. +* **d)** Convey the object code by offering access from a designated place (gratis or for +a charge), and offer equivalent access to the Corresponding Source in the same way +through the same place at no further charge. You need not require recipients to copy +the Corresponding Source along with the object code. If the place to copy the object +code is a network server, the Corresponding Source may be on a different server +(operated by you or a third party) that supports equivalent copying facilities, +provided you maintain clear directions next to the object code saying where to find +the Corresponding Source. Regardless of what server hosts the Corresponding Source, +you remain obligated to ensure that it is available for as long as needed to satisfy +these requirements. +* **e)** Convey the object code using peer-to-peer transmission, provided you inform +other peers where the object code and Corresponding Source of the work are being +offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the +Corresponding Source as a System Library, need not be included in conveying the +object code work. + +A “User Product” is either **(1)** a “consumer product”, which +means any tangible personal property which is normally used for personal, family, or +household purposes, or **(2)** anything designed or sold for incorporation into a +dwelling. In determining whether a product is a consumer product, doubtful cases +shall be resolved in favor of coverage. For a particular product received by a +particular user, “normally used” refers to a typical or common use of +that class of product, regardless of the status of the particular user or of the way +in which the particular user actually uses, or expects or is expected to use, the +product. A product is a consumer product regardless of whether the product has +substantial commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, +procedures, authorization keys, or other information required to install and execute +modified versions of a covered work in that User Product from a modified version of +its Corresponding Source. The information must suffice to ensure that the continued +functioning of the modified object code is in no case prevented or interfered with +solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for +use in, a User Product, and the conveying occurs as part of a transaction in which +the right of possession and use of the User Product is transferred to the recipient +in perpetuity or for a fixed term (regardless of how the transaction is +characterized), the Corresponding Source conveyed under this section must be +accompanied by the Installation Information. But this requirement does not apply if +neither you nor any third party retains the ability to install modified object code +on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to +continue to provide support service, warranty, or updates for a work that has been +modified or installed by the recipient, or for the User Product in which it has been +modified or installed. Access to a network may be denied when the modification itself +materially and adversely affects the operation of the network or violates the rules +and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with +this section must be in a format that is publicly documented (and with an +implementation available to the public in source code form), and must require no +special password or key for unpacking, reading or copying. + +### 7. Additional Terms + +“Additional permissions” are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. Additional +permissions that are applicable to the entire Program shall be treated as though they +were included in this License, to the extent that they are valid under applicable +law. If additional permissions apply only to part of the Program, that part may be +used separately under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any +additional permissions from that copy, or from any part of it. (Additional +permissions may be written to require their own removal in certain cases when you +modify the work.) You may place additional permissions on material, added by you to a +covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a +covered work, you may (if authorized by the copyright holders of that material) +supplement the terms of this License with terms: + +* **a)** Disclaiming warranty or limiting liability differently from the terms of +sections 15 and 16 of this License; or +* **b)** Requiring preservation of specified reasonable legal notices or author +attributions in that material or in the Appropriate Legal Notices displayed by works +containing it; or +* **c)** Prohibiting misrepresentation of the origin of that material, or requiring that +modified versions of such material be marked in reasonable ways as different from the +original version; or +* **d)** Limiting the use for publicity purposes of names of licensors or authors of the +material; or +* **e)** Declining to grant rights under trademark law for use of some trade names, +trademarks, or service marks; or +* **f)** Requiring indemnification of licensors and authors of that material by anyone +who conveys the material (or modified versions of it) with contractual assumptions of +liability to the recipient, for any liability that these contractual assumptions +directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further +restrictions” within the meaning of section 10. If the Program as you received +it, or any part of it, contains a notice stating that it is governed by this License +along with a term that is a further restriction, you may remove that term. If a +license document contains a further restriction but permits relicensing or conveying +under this License, you may add to a covered work material governed by the terms of +that license document, provided that the further restriction does not survive such +relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in +the relevant source files, a statement of the additional terms that apply to those +files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a +separately written license, or stated as exceptions; the above requirements apply +either way. + +### 8. Termination + +You may not propagate or modify a covered work except as expressly provided under +this License. Any attempt otherwise to propagate or modify it is void, and will +automatically terminate your rights under this License (including any patent licenses +granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a +particular copyright holder is reinstated **(a)** provisionally, unless and until the +copyright holder explicitly and finally terminates your license, and **(b)** permanently, +if the copyright holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently +if the copyright holder notifies you of the violation by some reasonable means, this +is the first time you have received notice of violation of this License (for any +work) from that copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of +parties who have received copies or rights from you under this License. If your +rights have been terminated and not permanently reinstated, you do not qualify to +receive new licenses for the same material under section 10. + +### 9. Acceptance Not Required for Having Copies + +You are not required to accept this License in order to receive or run a copy of the +Program. Ancillary propagation of a covered work occurring solely as a consequence of +using peer-to-peer transmission to receive a copy likewise does not require +acceptance. However, nothing other than this License grants you permission to +propagate or modify any covered work. These actions infringe copyright if you do not +accept this License. Therefore, by modifying or propagating a covered work, you +indicate your acceptance of this License to do so. + +### 10. Automatic Licensing of Downstream Recipients + +Each time you convey a covered work, the recipient automatically receives a license +from the original licensors, to run, modify and propagate that work, subject to this +License. You are not responsible for enforcing compliance by third parties with this +License. + +An “entity transaction” is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an organization, or +merging organizations. If propagation of a covered work results from an entity +transaction, each party to that transaction who receives a copy of the work also +receives whatever licenses to the work the party's predecessor in interest had or +could give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if the predecessor +has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or +affirmed under this License. For example, you may not impose a license fee, royalty, +or other charge for exercise of rights granted under this License, and you may not +initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging +that any patent claim is infringed by making, using, selling, offering for sale, or +importing the Program or any portion of it. + +### 11. Patents + +A “contributor” is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The work thus +licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or +controlled by the contributor, whether already acquired or hereafter acquired, that +would be infringed by some manner, permitted by this License, of making, using, or +selling its contributor version, but do not include claims that would be infringed +only as a consequence of further modification of the contributor version. For +purposes of this definition, “control” includes the right to grant patent +sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license +under the contributor's essential patent claims, to make, use, sell, offer for sale, +import and otherwise run, modify and propagate the contents of its contributor +version. + +In the following three paragraphs, a “patent license” is any express +agreement or commitment, however denominated, not to enforce a patent (such as an +express permission to practice a patent or covenant not to sue for patent +infringement). To “grant” such a patent license to a party means to make +such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the +Corresponding Source of the work is not available for anyone to copy, free of charge +and under the terms of this License, through a publicly available network server or +other readily accessible means, then you must either **(1)** cause the Corresponding +Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the +patent license for this particular work, or **(3)** arrange, in a manner consistent with +the requirements of this License, to extend the patent license to downstream +recipients. “Knowingly relying” means you have actual knowledge that, but +for the patent license, your conveying the covered work in a country, or your +recipient's use of the covered work in a country, would infringe one or more +identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you +convey, or propagate by procuring conveyance of, a covered work, and grant a patent +license to some of the parties receiving the covered work authorizing them to use, +propagate, modify or convey a specific copy of the covered work, then the patent +license you grant is automatically extended to all recipients of the covered work and +works based on it. + +A patent license is “discriminatory” if it does not include within the +scope of its coverage, prohibits the exercise of, or is conditioned on the +non-exercise of one or more of the rights that are specifically granted under this +License. You may not convey a covered work if you are a party to an arrangement with +a third party that is in the business of distributing software, under which you make +payment to the third party based on the extent of your activity of conveying the +work, and under which the third party grants, to any of the parties who would receive +the covered work from you, a discriminatory patent license **(a)** in connection with +copies of the covered work conveyed by you (or copies made from those copies), or **(b)** +primarily for and in connection with specific products or compilations that contain +the covered work, unless you entered into that arrangement, or that patent license +was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied +license or other defenses to infringement that may otherwise be available to you +under applicable patent law. + +### 12. No Surrender of Others' Freedom + +If conditions are imposed on you (whether by court order, agreement or otherwise) +that contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot convey a covered work so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not convey it at all. For example, if you +agree to terms that obligate you to collect a royalty for further conveying from +those to whom you convey the Program, the only way you could satisfy both those terms +and this License would be to refrain entirely from conveying the Program. + +### 13. Use with the GNU Affero General Public License + +Notwithstanding any other provision of this License, you have permission to link or +combine any covered work with a work licensed under version 3 of the GNU Affero +General Public License into a single combined work, and to convey the resulting work. +The terms of this License will continue to apply to the part which is the covered +work, but the special requirements of the GNU Affero General Public License, section +13, concerning interaction through a network will apply to the combination as such. + +### 14. Revised Versions of this License + +The Free Software Foundation may publish revised and/or new versions of the GNU +General Public License from time to time. Such new versions will be similar in spirit +to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that +a certain numbered version of the GNU General Public License “or any later +version” applies to it, you have the option of following the terms and +conditions either of that numbered version or of any later version published by the +Free Software Foundation. If the Program does not specify a version number of the GNU +General Public License, you may choose any version ever published by the Free +Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU +General Public License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no +additional obligations are imposed on any author or copyright holder as a result of +your choosing to follow a later version. + +### 15. Disclaimer of Warranty + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE +QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE +DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +### 16. Limitation of Liability + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY +COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS +PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, +INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE +OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE +WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +### 17. Interpretation of Sections 15 and 16 + +If the disclaimer of warranty and limitation of liability provided above cannot be +given local legal effect according to their terms, reviewing courts shall apply local +law that most closely approximates an absolute waiver of all civil liability in +connection with the Program, unless a warranty or assumption of liability accompanies +a copy of the Program in return for a fee. + +_END OF TERMS AND CONDITIONS_ + +## How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to +the public, the best way to achieve this is to make it free software which everyone +can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them +to the start of each source file to most effectively state the exclusion of warranty; +and each file should have at least the “copyright” line and a pointer to +where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this +when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type 'show c' for details. + +The hypothetical commands `show w` and `show c` should show the appropriate parts of +the General Public License. Of course, your program's commands might be different; +for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to +sign a “copyright disclaimer” for the program, if necessary. For more +information on this, and how to apply and follow the GNU GPL, see +<>. + +The GNU General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may consider it +more useful to permit linking proprietary applications with the library. If this is +what you want to do, use the GNU Lesser General Public License instead of this +License. But first, please read +<>. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4328b91 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +.PHONY: build test shell clean + +build: + docker build -t habre_pm . + +test: + docker run --rm -v "${PWD}/test":/tmp habre_pm my_address_file_geocoded.csv + +shell: + docker run --rm -it --entrypoint=/bin/bash -v "${PWD}/test":/tmp habre_pm + +clean: + docker system prune -f \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fd2dff7 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# habre_pm + +[![](https://img.shields.io/github/v/release/degauss-org/habre_pm?color=469FC2&label=version&sort=semver)](https://github.com/degauss-org/habre_pm/releases) +[![container build status](https://github.com/degauss-org/habre_pm/workflows/build-deploy-release/badge.svg)](https://github.com/degauss-org/habre_pm/actions/workflows/build-deploy-release.yaml) + +## Using + +If `my_address_file_geocoded.csv` is a file in the current working directory with coordinate columns named `lat` and `lon`, then the [DeGAUSS command](https://degauss.org/using_degauss.html#DeGAUSS_Commands): + +```sh +docker run --rm -v $PWD:/tmp ghcr.io/degauss-org/habre_pm:0.1.0 my_address_file_geocoded.csv +``` + +will produce `my_address_file_geocoded_habre_pm_0.1.0.csv` with added columns: + +- **`this_geomarker`**: a definition of this geomarker +- **`that_geomarker`**: a definition of that geomarker + +### Optional Argument + +- If this DeGAUSS container takes an optional argument, describe its usage and effects here. +- Be sure to also update the example output file name with the argument value. + +## Geomarker Methods + +- If needed, put details here about the methods and assumptions used in the geomarker assessment process. + +## Geomarker Data + +- List how geomarker was created, ideally including any scripts within the repo used to do so or linking to an external repository +- If applicable, list where geomarker data is stored in S3 using a hyperlink like: [`s3://path/to/habre_pm.rds`](https://geomarker.s3.us-east-2.amazonaws.com/path/to/habre_pm.rds) + +## DeGAUSS Details + +For detailed documentation on DeGAUSS, including general usage and installation, please see the [DeGAUSS homepage](https://degauss.org). \ No newline at end of file diff --git a/entrypoint.R b/entrypoint.R new file mode 100755 index 0000000..2f0af24 --- /dev/null +++ b/entrypoint.R @@ -0,0 +1,85 @@ +#!/usr/local/bin/Rscript + +dht::greeting() + +## load libraries without messages or warnings +withr::with_message_sink("/dev/null", library(dplyr)) +withr::with_message_sink("/dev/null", library(tidyr)) +withr::with_message_sink("/dev/null", library(sf)) +withr::with_message_sink("/dev/null", library(terra)) +withr::with_message_sink("/dev/null", library(lubridate)) +withr::with_message_sink("/dev/null", library(dht)) +withr::with_message_sink("/dev/null", library(readr)) + +doc <- " + Usage: + entrypoint.R + " + +opt <- docopt::docopt(doc) + +## for interactive testing +## opt <- docopt::docopt(doc, args = 'test/my_address_file_geocoded.csv') + +message("reading input file...") +d <- dht::read_lat_lon_csv(opt$filename, nest_df = F, sf = F) + +dht::check_for_column(d, "lat", d$lat) +dht::check_for_column(d, "lon", d$lon) +dht::check_for_column(d, "start_date", d$start_date) +dht::check_for_column(d, "end_date", d$end_date) + + +d$start_date <- dht::check_dates(d$start_date) +d$end_date <- dht::check_dates(d$end_date) +dht::check_end_after_start_date(d$start_date, d$end_date) + +# read in tif and date lookup +r <- terra::rast("/app/habre.tif") + +date_lookup <- readr::read_csv("/app/pm25_iweek_startdate.csv") |> + dht::expand_dates(by = "day") |> + dplyr::select(week = iweek, date) + +# expand dates +d_daily <- dht::expand_dates(d, by = "day") + +# join to get week number +d_week <- d_daily |> + dplyr::left_join(date_lookup, by = "date") + +d_dedup <- d_week |> + select(lat, lon, week) |> + group_by(lat, lon, week) |> + filter(!duplicated(lat, lon, week)) |> + mutate(layer_name_mean = glue::glue("week{week}_mean"), + layer_name_sd = glue::glue("week{week}_std")) + +d_for_extract <- d_dedup |> + st_as_sf(coords = c("lon", "lat"), crs = 4326) |> + st_transform(st_crs(r)) |> + terra::vect() + +d_pm <- terra::extract(r, + d_for_extract, + layer = "layer_name_mean") + +d_sd <- terra::extract(r, + d_for_extract, + layer = "layer_name_sd") + +d_dedup <- d_dedup |> + ungroup() |> + mutate(pm = d_pm$value, + sd = d_sd$value) + +d_out <- left_join(d_week, d_dedup, by = c("lat", "lon", "week")) |> + group_by(.row) |> + summarize(pm = round(sum(pm)/n(),2), + sd = round(sum(sd)/n(),2)) + +d_out <- left_join(d, d_out, by = ".row") |> + select(-.row) + +## merge back on .row after unnesting .rows into .row +dht::write_geomarker_file(d = d_out, filename = opt$filename) diff --git a/habre.tif b/habre.tif new file mode 100644 index 0000000..60e1140 Binary files /dev/null and b/habre.tif differ diff --git a/pm25_iweek_startdate.csv b/pm25_iweek_startdate.csv new file mode 100644 index 0000000..d6502f3 --- /dev/null +++ b/pm25_iweek_startdate.csv @@ -0,0 +1,523 @@ +"iweek","start_date","end_date" +410,2007-12-31,2008-01-06 +411,2008-01-07,2008-01-13 +412,2008-01-14,2008-01-20 +413,2008-01-21,2008-01-27 +414,2008-01-28,2008-02-03 +415,2008-02-04,2008-02-10 +416,2008-02-11,2008-02-17 +417,2008-02-18,2008-02-24 +418,2008-02-25,2008-03-02 +419,2008-03-03,2008-03-09 +420,2008-03-10,2008-03-16 +421,2008-03-17,2008-03-23 +422,2008-03-24,2008-03-30 +423,2008-03-31,2008-04-06 +424,2008-04-07,2008-04-13 +425,2008-04-14,2008-04-20 +426,2008-04-21,2008-04-27 +427,2008-04-28,2008-05-04 +428,2008-05-05,2008-05-11 +429,2008-05-12,2008-05-18 +430,2008-05-19,2008-05-25 +431,2008-05-26,2008-06-01 +432,2008-06-02,2008-06-08 +433,2008-06-09,2008-06-15 +434,2008-06-16,2008-06-22 +435,2008-06-23,2008-06-29 +436,2008-06-30,2008-07-06 +437,2008-07-07,2008-07-13 +438,2008-07-14,2008-07-20 +439,2008-07-21,2008-07-27 +440,2008-07-28,2008-08-03 +441,2008-08-04,2008-08-10 +442,2008-08-11,2008-08-17 +443,2008-08-18,2008-08-24 +444,2008-08-25,2008-08-31 +445,2008-09-01,2008-09-07 +446,2008-09-08,2008-09-14 +447,2008-09-15,2008-09-21 +448,2008-09-22,2008-09-28 +449,2008-09-29,2008-10-05 +450,2008-10-06,2008-10-12 +451,2008-10-13,2008-10-19 +452,2008-10-20,2008-10-26 +453,2008-10-27,2008-11-02 +454,2008-11-03,2008-11-09 +455,2008-11-10,2008-11-16 +456,2008-11-17,2008-11-23 +457,2008-11-24,2008-11-30 +458,2008-12-01,2008-12-07 +459,2008-12-08,2008-12-14 +460,2008-12-15,2008-12-21 +461,2008-12-22,2008-12-28 +462,2008-12-29,2009-01-04 +463,2009-01-05,2009-01-11 +464,2009-01-12,2009-01-18 +465,2009-01-19,2009-01-25 +466,2009-01-26,2009-02-01 +467,2009-02-02,2009-02-08 +468,2009-02-09,2009-02-15 +469,2009-02-16,2009-02-22 +470,2009-02-23,2009-03-01 +471,2009-03-02,2009-03-08 +472,2009-03-09,2009-03-15 +473,2009-03-16,2009-03-22 +474,2009-03-23,2009-03-29 +475,2009-03-30,2009-04-05 +476,2009-04-06,2009-04-12 +477,2009-04-13,2009-04-19 +478,2009-04-20,2009-04-26 +479,2009-04-27,2009-05-03 +480,2009-05-04,2009-05-10 +481,2009-05-11,2009-05-17 +482,2009-05-18,2009-05-24 +483,2009-05-25,2009-05-31 +484,2009-06-01,2009-06-07 +485,2009-06-08,2009-06-14 +486,2009-06-15,2009-06-21 +487,2009-06-22,2009-06-28 +488,2009-06-29,2009-07-05 +489,2009-07-06,2009-07-12 +490,2009-07-13,2009-07-19 +491,2009-07-20,2009-07-26 +492,2009-07-27,2009-08-02 +493,2009-08-03,2009-08-09 +494,2009-08-10,2009-08-16 +495,2009-08-17,2009-08-23 +496,2009-08-24,2009-08-30 +497,2009-08-31,2009-09-06 +498,2009-09-07,2009-09-13 +499,2009-09-14,2009-09-20 +500,2009-09-21,2009-09-27 +501,2009-09-28,2009-10-04 +502,2009-10-05,2009-10-11 +503,2009-10-12,2009-10-18 +504,2009-10-19,2009-10-25 +505,2009-10-26,2009-11-01 +506,2009-11-02,2009-11-08 +507,2009-11-09,2009-11-15 +508,2009-11-16,2009-11-22 +509,2009-11-23,2009-11-29 +510,2009-11-30,2009-12-06 +511,2009-12-07,2009-12-13 +512,2009-12-14,2009-12-20 +513,2009-12-21,2009-12-27 +514,2009-12-28,2010-01-03 +515,2010-01-04,2010-01-10 +516,2010-01-11,2010-01-17 +517,2010-01-18,2010-01-24 +518,2010-01-25,2010-01-31 +519,2010-02-01,2010-02-07 +520,2010-02-08,2010-02-14 +521,2010-02-15,2010-02-21 +522,2010-02-22,2010-02-28 +523,2010-03-01,2010-03-07 +524,2010-03-08,2010-03-14 +525,2010-03-15,2010-03-21 +526,2010-03-22,2010-03-28 +527,2010-03-29,2010-04-04 +528,2010-04-05,2010-04-11 +529,2010-04-12,2010-04-18 +530,2010-04-19,2010-04-25 +531,2010-04-26,2010-05-02 +532,2010-05-03,2010-05-09 +533,2010-05-10,2010-05-16 +534,2010-05-17,2010-05-23 +535,2010-05-24,2010-05-30 +536,2010-05-31,2010-06-06 +537,2010-06-07,2010-06-13 +538,2010-06-14,2010-06-20 +539,2010-06-21,2010-06-27 +540,2010-06-28,2010-07-04 +541,2010-07-05,2010-07-11 +542,2010-07-12,2010-07-18 +543,2010-07-19,2010-07-25 +544,2010-07-26,2010-08-01 +545,2010-08-02,2010-08-08 +546,2010-08-09,2010-08-15 +547,2010-08-16,2010-08-22 +548,2010-08-23,2010-08-29 +549,2010-08-30,2010-09-05 +550,2010-09-06,2010-09-12 +551,2010-09-13,2010-09-19 +552,2010-09-20,2010-09-26 +553,2010-09-27,2010-10-03 +554,2010-10-04,2010-10-10 +555,2010-10-11,2010-10-17 +556,2010-10-18,2010-10-24 +557,2010-10-25,2010-10-31 +558,2010-11-01,2010-11-07 +559,2010-11-08,2010-11-14 +560,2010-11-15,2010-11-21 +561,2010-11-22,2010-11-28 +562,2010-11-29,2010-12-05 +563,2010-12-06,2010-12-12 +564,2010-12-13,2010-12-19 +565,2010-12-20,2010-12-26 +566,2010-12-27,2011-01-02 +567,2011-01-03,2011-01-09 +568,2011-01-10,2011-01-16 +569,2011-01-17,2011-01-23 +570,2011-01-24,2011-01-30 +571,2011-01-31,2011-02-06 +572,2011-02-07,2011-02-13 +573,2011-02-14,2011-02-20 +574,2011-02-21,2011-02-27 +575,2011-02-28,2011-03-06 +576,2011-03-07,2011-03-13 +577,2011-03-14,2011-03-20 +578,2011-03-21,2011-03-27 +579,2011-03-28,2011-04-03 +580,2011-04-04,2011-04-10 +581,2011-04-11,2011-04-17 +582,2011-04-18,2011-04-24 +583,2011-04-25,2011-05-01 +584,2011-05-02,2011-05-08 +585,2011-05-09,2011-05-15 +586,2011-05-16,2011-05-22 +587,2011-05-23,2011-05-29 +588,2011-05-30,2011-06-05 +589,2011-06-06,2011-06-12 +590,2011-06-13,2011-06-19 +591,2011-06-20,2011-06-26 +592,2011-06-27,2011-07-03 +593,2011-07-04,2011-07-10 +594,2011-07-11,2011-07-17 +595,2011-07-18,2011-07-24 +596,2011-07-25,2011-07-31 +597,2011-08-01,2011-08-07 +598,2011-08-08,2011-08-14 +599,2011-08-15,2011-08-21 +600,2011-08-22,2011-08-28 +601,2011-08-29,2011-09-04 +602,2011-09-05,2011-09-11 +603,2011-09-12,2011-09-18 +604,2011-09-19,2011-09-25 +605,2011-09-26,2011-10-02 +606,2011-10-03,2011-10-09 +607,2011-10-10,2011-10-16 +608,2011-10-17,2011-10-23 +609,2011-10-24,2011-10-30 +610,2011-10-31,2011-11-06 +611,2011-11-07,2011-11-13 +612,2011-11-14,2011-11-20 +613,2011-11-21,2011-11-27 +614,2011-11-28,2011-12-04 +615,2011-12-05,2011-12-11 +616,2011-12-12,2011-12-18 +617,2011-12-19,2011-12-25 +618,2011-12-26,2012-01-01 +619,2012-01-02,2012-01-08 +620,2012-01-09,2012-01-15 +621,2012-01-16,2012-01-22 +622,2012-01-23,2012-01-29 +623,2012-01-30,2012-02-05 +624,2012-02-06,2012-02-12 +625,2012-02-13,2012-02-19 +626,2012-02-20,2012-02-26 +627,2012-02-27,2012-03-04 +628,2012-03-05,2012-03-11 +629,2012-03-12,2012-03-18 +630,2012-03-19,2012-03-25 +631,2012-03-26,2012-04-01 +632,2012-04-02,2012-04-08 +633,2012-04-09,2012-04-15 +634,2012-04-16,2012-04-22 +635,2012-04-23,2012-04-29 +636,2012-04-30,2012-05-06 +637,2012-05-07,2012-05-13 +638,2012-05-14,2012-05-20 +639,2012-05-21,2012-05-27 +640,2012-05-28,2012-06-03 +641,2012-06-04,2012-06-10 +642,2012-06-11,2012-06-17 +643,2012-06-18,2012-06-24 +644,2012-06-25,2012-07-01 +645,2012-07-02,2012-07-08 +646,2012-07-09,2012-07-15 +647,2012-07-16,2012-07-22 +648,2012-07-23,2012-07-29 +649,2012-07-30,2012-08-05 +650,2012-08-06,2012-08-12 +651,2012-08-13,2012-08-19 +652,2012-08-20,2012-08-26 +653,2012-08-27,2012-09-02 +654,2012-09-03,2012-09-09 +655,2012-09-10,2012-09-16 +656,2012-09-17,2012-09-23 +657,2012-09-24,2012-09-30 +658,2012-10-01,2012-10-07 +659,2012-10-08,2012-10-14 +660,2012-10-15,2012-10-21 +661,2012-10-22,2012-10-28 +662,2012-10-29,2012-11-04 +663,2012-11-05,2012-11-11 +664,2012-11-12,2012-11-18 +665,2012-11-19,2012-11-25 +666,2012-11-26,2012-12-02 +667,2012-12-03,2012-12-09 +668,2012-12-10,2012-12-16 +669,2012-12-17,2012-12-23 +670,2012-12-24,2012-12-30 +671,2012-12-31,2013-01-06 +672,2013-01-07,2013-01-13 +673,2013-01-14,2013-01-20 +674,2013-01-21,2013-01-27 +675,2013-01-28,2013-02-03 +676,2013-02-04,2013-02-10 +677,2013-02-11,2013-02-17 +678,2013-02-18,2013-02-24 +679,2013-02-25,2013-03-03 +680,2013-03-04,2013-03-10 +681,2013-03-11,2013-03-17 +682,2013-03-18,2013-03-24 +683,2013-03-25,2013-03-31 +684,2013-04-01,2013-04-07 +685,2013-04-08,2013-04-14 +686,2013-04-15,2013-04-21 +687,2013-04-22,2013-04-28 +688,2013-04-29,2013-05-05 +689,2013-05-06,2013-05-12 +690,2013-05-13,2013-05-19 +691,2013-05-20,2013-05-26 +692,2013-05-27,2013-06-02 +693,2013-06-03,2013-06-09 +694,2013-06-10,2013-06-16 +695,2013-06-17,2013-06-23 +696,2013-06-24,2013-06-30 +697,2013-07-01,2013-07-07 +698,2013-07-08,2013-07-14 +699,2013-07-15,2013-07-21 +700,2013-07-22,2013-07-28 +701,2013-07-29,2013-08-04 +702,2013-08-05,2013-08-11 +703,2013-08-12,2013-08-18 +704,2013-08-19,2013-08-25 +705,2013-08-26,2013-09-01 +706,2013-09-02,2013-09-08 +707,2013-09-09,2013-09-15 +708,2013-09-16,2013-09-22 +709,2013-09-23,2013-09-29 +710,2013-09-30,2013-10-06 +711,2013-10-07,2013-10-13 +712,2013-10-14,2013-10-20 +713,2013-10-21,2013-10-27 +714,2013-10-28,2013-11-03 +715,2013-11-04,2013-11-10 +716,2013-11-11,2013-11-17 +717,2013-11-18,2013-11-24 +718,2013-11-25,2013-12-01 +719,2013-12-02,2013-12-08 +720,2013-12-09,2013-12-15 +721,2013-12-16,2013-12-22 +722,2013-12-23,2013-12-29 +723,2013-12-30,2014-01-05 +724,2014-01-06,2014-01-12 +725,2014-01-13,2014-01-19 +726,2014-01-20,2014-01-26 +727,2014-01-27,2014-02-02 +728,2014-02-03,2014-02-09 +729,2014-02-10,2014-02-16 +730,2014-02-17,2014-02-23 +731,2014-02-24,2014-03-02 +732,2014-03-03,2014-03-09 +733,2014-03-10,2014-03-16 +734,2014-03-17,2014-03-23 +735,2014-03-24,2014-03-30 +736,2014-03-31,2014-04-06 +737,2014-04-07,2014-04-13 +738,2014-04-14,2014-04-20 +739,2014-04-21,2014-04-27 +740,2014-04-28,2014-05-04 +741,2014-05-05,2014-05-11 +742,2014-05-12,2014-05-18 +743,2014-05-19,2014-05-25 +744,2014-05-26,2014-06-01 +745,2014-06-02,2014-06-08 +746,2014-06-09,2014-06-15 +747,2014-06-16,2014-06-22 +748,2014-06-23,2014-06-29 +749,2014-06-30,2014-07-06 +750,2014-07-07,2014-07-13 +751,2014-07-14,2014-07-20 +752,2014-07-21,2014-07-27 +753,2014-07-28,2014-08-03 +754,2014-08-04,2014-08-10 +755,2014-08-11,2014-08-17 +756,2014-08-18,2014-08-24 +757,2014-08-25,2014-08-31 +758,2014-09-01,2014-09-07 +759,2014-09-08,2014-09-14 +760,2014-09-15,2014-09-21 +761,2014-09-22,2014-09-28 +762,2014-09-29,2014-10-05 +763,2014-10-06,2014-10-12 +764,2014-10-13,2014-10-19 +765,2014-10-20,2014-10-26 +766,2014-10-27,2014-11-02 +767,2014-11-03,2014-11-09 +768,2014-11-10,2014-11-16 +769,2014-11-17,2014-11-23 +770,2014-11-24,2014-11-30 +771,2014-12-01,2014-12-07 +772,2014-12-08,2014-12-14 +773,2014-12-15,2014-12-21 +774,2014-12-22,2014-12-28 +775,2014-12-29,2015-01-04 +776,2015-01-05,2015-01-11 +777,2015-01-12,2015-01-18 +778,2015-01-19,2015-01-25 +779,2015-01-26,2015-02-01 +780,2015-02-02,2015-02-08 +781,2015-02-09,2015-02-15 +782,2015-02-16,2015-02-22 +783,2015-02-23,2015-03-01 +784,2015-03-02,2015-03-08 +785,2015-03-09,2015-03-15 +786,2015-03-16,2015-03-22 +787,2015-03-23,2015-03-29 +788,2015-03-30,2015-04-05 +789,2015-04-06,2015-04-12 +790,2015-04-13,2015-04-19 +791,2015-04-20,2015-04-26 +792,2015-04-27,2015-05-03 +793,2015-05-04,2015-05-10 +794,2015-05-11,2015-05-17 +795,2015-05-18,2015-05-24 +796,2015-05-25,2015-05-31 +797,2015-06-01,2015-06-07 +798,2015-06-08,2015-06-14 +799,2015-06-15,2015-06-21 +800,2015-06-22,2015-06-28 +801,2015-06-29,2015-07-05 +802,2015-07-06,2015-07-12 +803,2015-07-13,2015-07-19 +804,2015-07-20,2015-07-26 +805,2015-07-27,2015-08-02 +806,2015-08-03,2015-08-09 +807,2015-08-10,2015-08-16 +808,2015-08-17,2015-08-23 +809,2015-08-24,2015-08-30 +810,2015-08-31,2015-09-06 +811,2015-09-07,2015-09-13 +812,2015-09-14,2015-09-20 +813,2015-09-21,2015-09-27 +814,2015-09-28,2015-10-04 +815,2015-10-05,2015-10-11 +816,2015-10-12,2015-10-18 +817,2015-10-19,2015-10-25 +818,2015-10-26,2015-11-01 +819,2015-11-02,2015-11-08 +820,2015-11-09,2015-11-15 +821,2015-11-16,2015-11-22 +822,2015-11-23,2015-11-29 +823,2015-11-30,2015-12-06 +824,2015-12-07,2015-12-13 +825,2015-12-14,2015-12-20 +826,2015-12-21,2015-12-27 +827,2015-12-28,2016-01-03 +828,2016-01-04,2016-01-10 +829,2016-01-11,2016-01-17 +830,2016-01-18,2016-01-24 +831,2016-01-25,2016-01-31 +832,2016-02-01,2016-02-07 +833,2016-02-08,2016-02-14 +834,2016-02-15,2016-02-21 +835,2016-02-22,2016-02-28 +836,2016-02-29,2016-03-06 +837,2016-03-07,2016-03-13 +838,2016-03-14,2016-03-20 +839,2016-03-21,2016-03-27 +840,2016-03-28,2016-04-03 +841,2016-04-04,2016-04-10 +842,2016-04-11,2016-04-17 +843,2016-04-18,2016-04-24 +844,2016-04-25,2016-05-01 +845,2016-05-02,2016-05-08 +846,2016-05-09,2016-05-15 +847,2016-05-16,2016-05-22 +848,2016-05-23,2016-05-29 +849,2016-05-30,2016-06-05 +850,2016-06-06,2016-06-12 +851,2016-06-13,2016-06-19 +852,2016-06-20,2016-06-26 +853,2016-06-27,2016-07-03 +854,2016-07-04,2016-07-10 +855,2016-07-11,2016-07-17 +856,2016-07-18,2016-07-24 +857,2016-07-25,2016-07-31 +858,2016-08-01,2016-08-07 +859,2016-08-08,2016-08-14 +860,2016-08-15,2016-08-21 +861,2016-08-22,2016-08-28 +862,2016-08-29,2016-09-04 +863,2016-09-05,2016-09-11 +864,2016-09-12,2016-09-18 +865,2016-09-19,2016-09-25 +866,2016-09-26,2016-10-02 +867,2016-10-03,2016-10-09 +868,2016-10-10,2016-10-16 +869,2016-10-17,2016-10-23 +870,2016-10-24,2016-10-30 +871,2016-10-31,2016-11-06 +872,2016-11-07,2016-11-13 +873,2016-11-14,2016-11-20 +874,2016-11-21,2016-11-27 +875,2016-11-28,2016-12-04 +876,2016-12-05,2016-12-11 +877,2016-12-12,2016-12-18 +878,2016-12-19,2016-12-25 +879,2016-12-26,2017-01-01 +880,2017-01-02,2017-01-08 +881,2017-01-09,2017-01-15 +882,2017-01-16,2017-01-22 +883,2017-01-23,2017-01-29 +884,2017-01-30,2017-02-05 +885,2017-02-06,2017-02-12 +886,2017-02-13,2017-02-19 +887,2017-02-20,2017-02-26 +888,2017-02-27,2017-03-05 +889,2017-03-06,2017-03-12 +890,2017-03-13,2017-03-19 +891,2017-03-20,2017-03-26 +892,2017-03-27,2017-04-02 +893,2017-04-03,2017-04-09 +894,2017-04-10,2017-04-16 +895,2017-04-17,2017-04-23 +896,2017-04-24,2017-04-30 +897,2017-05-01,2017-05-07 +898,2017-05-08,2017-05-14 +899,2017-05-15,2017-05-21 +900,2017-05-22,2017-05-28 +901,2017-05-29,2017-06-04 +902,2017-06-05,2017-06-11 +903,2017-06-12,2017-06-18 +904,2017-06-19,2017-06-25 +905,2017-06-26,2017-07-02 +906,2017-07-03,2017-07-09 +907,2017-07-10,2017-07-16 +908,2017-07-17,2017-07-23 +909,2017-07-24,2017-07-30 +910,2017-07-31,2017-08-06 +911,2017-08-07,2017-08-13 +912,2017-08-14,2017-08-20 +913,2017-08-21,2017-08-27 +914,2017-08-28,2017-09-03 +915,2017-09-04,2017-09-10 +916,2017-09-11,2017-09-17 +917,2017-09-18,2017-09-24 +918,2017-09-25,2017-10-01 +919,2017-10-02,2017-10-08 +920,2017-10-09,2017-10-15 +921,2017-10-16,2017-10-22 +922,2017-10-23,2017-10-29 +923,2017-10-30,2017-11-05 +924,2017-11-06,2017-11-12 +925,2017-11-13,2017-11-19 +926,2017-11-20,2017-11-26 +927,2017-11-27,2017-12-03 +928,2017-12-04,2017-12-10 +929,2017-12-11,2017-12-17 +930,2017-12-18,2017-12-24 +931,2017-12-25,2017-12-31 diff --git a/renv.lock b/renv.lock new file mode 100644 index 0000000..c65dbf9 --- /dev/null +++ b/renv.lock @@ -0,0 +1,595 @@ +{ + "R": { + "Version": "4.2.2", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cran.rstudio.com" + } + ] + }, + "Packages": { + "DBI": { + "Package": "DBI", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "b2866e62bab9378c3cc9476a1954226b", + "Requirements": [] + }, + "KernSmooth": { + "Package": "KernSmooth", + "Version": "2.23-20", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "8dcfa99b14c296bc9f1fd64d52fd3ce7", + "Requirements": [] + }, + "MASS": { + "Package": "MASS", + "Version": "7.3-58.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "762e1804143a332333c054759f89a706", + "Requirements": [] + }, + "R6": { + "Package": "R6", + "Version": "2.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "470851b6d5d0ac559e9d01bb352b4021", + "Requirements": [] + }, + "Rcpp": { + "Package": "Rcpp", + "Version": "1.0.9", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "e9c08b94391e9f3f97355841229124f2", + "Requirements": [] + }, + "bit": { + "Package": "bit", + "Version": "4.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "d242abec29412ce988848d0294b208fd", + "Requirements": [] + }, + "bit64": { + "Package": "bit64", + "Version": "4.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "9fe98599ca456d6552421db0d6772d8f", + "Requirements": [ + "bit" + ] + }, + "class": { + "Package": "class", + "Version": "7.3-20", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "da09d82223e669d270e47ed24ac8686e", + "Requirements": [ + "MASS" + ] + }, + "classInt": { + "Package": "classInt", + "Version": "0.4-8", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "298fa500d773db0845935cd73bfd9c2e", + "Requirements": [ + "KernSmooth", + "class", + "e1071" + ] + }, + "cli": { + "Package": "cli", + "Version": "3.4.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "0d297d01734d2bcea40197bd4971a764", + "Requirements": [] + }, + "clipr": { + "Package": "clipr", + "Version": "0.8.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "3f038e5ac7f41d4ac41ce658c85e3042", + "Requirements": [] + }, + "cpp11": { + "Package": "cpp11", + "Version": "0.4.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "ed588261931ee3be2c700d22e94a29ab", + "Requirements": [] + }, + "crayon": { + "Package": "crayon", + "Version": "1.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "e8a1e41acf02548751f45c718d55aa6a", + "Requirements": [] + }, + "dht": { + "Package": "dht", + "Version": "1.2.2", + "Source": "GitHub", + "RemoteType": "github", + "RemoteHost": "api.github.com", + "RemoteRepo": "dht", + "RemoteUsername": "degauss-org", + "RemoteRef": "HEAD", + "RemoteSha": "2b0ca86062933acb78b7aac8a313fe82afbbd6c1", + "Hash": "478477f82a65fe91f09d05fc69fe247f", + "Requirements": [ + "cli", + "dplyr", + "fs", + "glue", + "magrittr", + "prettyunits", + "ps", + "purrr", + "readr", + "stringr", + "tidyr", + "tidyselect", + "whisker", + "withr" + ] + }, + "docopt": { + "Package": "docopt", + "Version": "0.7.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "e9eeef7931ee99ca0093f3f20b88e09b", + "Requirements": [] + }, + "dplyr": { + "Package": "dplyr", + "Version": "1.0.10", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "539412282059f7f0c07295723d23f987", + "Requirements": [ + "R6", + "generics", + "glue", + "lifecycle", + "magrittr", + "pillar", + "rlang", + "tibble", + "tidyselect", + "vctrs" + ] + }, + "e1071": { + "Package": "e1071", + "Version": "1.7-12", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "0d776df7577206e100c2c4b508208b10", + "Requirements": [ + "class", + "proxy" + ] + }, + "ellipsis": { + "Package": "ellipsis", + "Version": "0.3.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077", + "Requirements": [ + "rlang" + ] + }, + "fansi": { + "Package": "fansi", + "Version": "1.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "83a8afdbe71839506baa9f90eebad7ec", + "Requirements": [] + }, + "fs": { + "Package": "fs", + "Version": "1.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "7c89603d81793f0d5486d91ab1fc6f1d", + "Requirements": [] + }, + "generics": { + "Package": "generics", + "Version": "0.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "15e9634c0fcd294799e9b2e929ed1b86", + "Requirements": [] + }, + "glue": { + "Package": "glue", + "Version": "1.6.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e", + "Requirements": [] + }, + "hms": { + "Package": "hms", + "Version": "1.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "41100392191e1244b887878b533eea91", + "Requirements": [ + "ellipsis", + "lifecycle", + "pkgconfig", + "rlang", + "vctrs" + ] + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "001cecbeac1cff9301bdc3775ee46a86", + "Requirements": [ + "cli", + "glue", + "rlang" + ] + }, + "lubridate": { + "Package": "lubridate", + "Version": "1.9.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "2af4550c2f0f7fbe7cbbf3dbf4ea3902", + "Requirements": [ + "generics", + "timechange" + ] + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "7ce2733a9826b3aeb1775d56fd305472", + "Requirements": [] + }, + "pillar": { + "Package": "pillar", + "Version": "1.8.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f2316df30902c81729ae9de95ad5a608", + "Requirements": [ + "cli", + "fansi", + "glue", + "lifecycle", + "rlang", + "utf8", + "vctrs" + ] + }, + "pkgconfig": { + "Package": "pkgconfig", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "01f28d4278f15c76cddbea05899c5d6f", + "Requirements": [] + }, + "prettyunits": { + "Package": "prettyunits", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "95ef9167b75dde9d2ccc3c7528393e7e", + "Requirements": [] + }, + "progress": { + "Package": "progress", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061", + "Requirements": [ + "R6", + "crayon", + "hms", + "prettyunits" + ] + }, + "proxy": { + "Package": "proxy", + "Version": "0.4-27", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "e0ef355c12942cf7a6b91a6cfaea8b3e", + "Requirements": [] + }, + "ps": { + "Package": "ps", + "Version": "1.7.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "68dd03d98a5efd1eb3012436de45ba83", + "Requirements": [] + }, + "purrr": { + "Package": "purrr", + "Version": "0.3.5", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "54842a2443c76267152eface28d9e90a", + "Requirements": [ + "magrittr", + "rlang" + ] + }, + "readr": { + "Package": "readr", + "Version": "2.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "2dfbfc673ccb3de3d8836b4b3bd23d14", + "Requirements": [ + "R6", + "cli", + "clipr", + "cpp11", + "crayon", + "hms", + "lifecycle", + "rlang", + "tibble", + "tzdb", + "vroom" + ] + }, + "renv": { + "Package": "renv", + "Version": "0.16.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "c9e8442ab69bc21c9697ecf856c1e6c7", + "Requirements": [] + }, + "rlang": { + "Package": "rlang", + "Version": "1.0.6", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "4ed1f8336c8d52c3e750adcdc57228a7", + "Requirements": [] + }, + "s2": { + "Package": "s2", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "328ea3dc4329fc40720456c8e0c75445", + "Requirements": [ + "Rcpp", + "wk" + ] + }, + "sf": { + "Package": "sf", + "Version": "1.0-9", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "8a348490fefb623e7935f405230900a7", + "Requirements": [ + "DBI", + "Rcpp", + "classInt", + "magrittr", + "s2", + "units" + ] + }, + "stringi": { + "Package": "stringi", + "Version": "1.7.8", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a68b980681bcbc84c7a67003fa796bfb", + "Requirements": [] + }, + "stringr": { + "Package": "stringr", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8", + "Requirements": [ + "cli", + "glue", + "lifecycle", + "magrittr", + "rlang", + "stringi", + "vctrs" + ] + }, + "terra": { + "Package": "terra", + "Version": "1.6-47", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "67b7ba63622fbab6820434ac7ac296d6", + "Requirements": [ + "Rcpp" + ] + }, + "tibble": { + "Package": "tibble", + "Version": "3.1.8", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "56b6934ef0f8c68225949a8672fe1a8f", + "Requirements": [ + "fansi", + "lifecycle", + "magrittr", + "pillar", + "pkgconfig", + "rlang", + "vctrs" + ] + }, + "tidyr": { + "Package": "tidyr", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "cdb403db0de33ccd1b6f53b83736efa8", + "Requirements": [ + "cpp11", + "dplyr", + "ellipsis", + "glue", + "lifecycle", + "magrittr", + "purrr", + "rlang", + "tibble", + "tidyselect", + "vctrs" + ] + }, + "tidyselect": { + "Package": "tidyselect", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "79540e5fcd9e0435af547d885f184fd5", + "Requirements": [ + "cli", + "glue", + "lifecycle", + "rlang", + "vctrs", + "withr" + ] + }, + "timechange": { + "Package": "timechange", + "Version": "0.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "4657195cc632097bb8d140d626b519fb", + "Requirements": [ + "cpp11" + ] + }, + "tzdb": { + "Package": "tzdb", + "Version": "0.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "b2e1cbce7c903eaf23ec05c58e59fb5e", + "Requirements": [ + "cpp11" + ] + }, + "units": { + "Package": "units", + "Version": "0.8-1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "81433967f9b34a120a4f5a5a016cd5ed", + "Requirements": [ + "Rcpp" + ] + }, + "utf8": { + "Package": "utf8", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "c9c462b759a5cc844ae25b5942654d13", + "Requirements": [] + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "970324f6572b4fd81db507b5d4062cb0", + "Requirements": [ + "cli", + "glue", + "lifecycle", + "rlang" + ] + }, + "vroom": { + "Package": "vroom", + "Version": "1.6.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "64f81fdead6e0d250fb041e175d123ab", + "Requirements": [ + "bit64", + "cli", + "cpp11", + "crayon", + "glue", + "hms", + "lifecycle", + "progress", + "rlang", + "tibble", + "tidyselect", + "tzdb", + "vctrs", + "withr" + ] + }, + "whisker": { + "Package": "whisker", + "Version": "0.4", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "ca970b96d894e90397ed20637a0c1bbe", + "Requirements": [] + }, + "withr": { + "Package": "withr", + "Version": "2.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "c0e49a9760983e81e55cdd9be92e7182", + "Requirements": [] + }, + "wk": { + "Package": "wk", + "Version": "0.7.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "141385279f2cd7faa6a3eccd8d1279dd", + "Requirements": [] + } + } +} diff --git a/renv/.gitignore b/renv/.gitignore new file mode 100644 index 0000000..0ec0cbb --- /dev/null +++ b/renv/.gitignore @@ -0,0 +1,7 @@ +library/ +local/ +cellar/ +lock/ +python/ +sandbox/ +staging/ diff --git a/renv/activate.R b/renv/activate.R new file mode 100644 index 0000000..019b5a6 --- /dev/null +++ b/renv/activate.R @@ -0,0 +1,994 @@ + +local({ + + # the requested version of renv + version <- "0.16.0" + + # the project directory + project <- getwd() + + # figure out whether the autoloader is enabled + enabled <- local({ + + # first, check config option + override <- getOption("renv.config.autoloader.enabled") + if (!is.null(override)) + return(override) + + # next, check environment variables + # TODO: prefer using the configuration one in the future + envvars <- c( + "RENV_CONFIG_AUTOLOADER_ENABLED", + "RENV_AUTOLOADER_ENABLED", + "RENV_ACTIVATE_PROJECT" + ) + + for (envvar in envvars) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(tolower(envval) %in% c("true", "t", "1")) + } + + # enable by default + TRUE + + }) + + if (!enabled) + return(FALSE) + + # avoid recursion + if (identical(getOption("renv.autoloader.running"), TRUE)) { + warning("ignoring recursive attempt to run renv autoloader") + return(invisible(TRUE)) + } + + # signal that we're loading renv during R startup + options(renv.autoloader.running = TRUE) + on.exit(options(renv.autoloader.running = NULL), add = TRUE) + + # signal that we've consented to use renv + options(renv.consent = TRUE) + + # load the 'utils' package eagerly -- this ensures that renv shims, which + # mask 'utils' packages, will come first on the search path + library(utils, lib.loc = .Library) + + # unload renv if it's already been loaded + if ("renv" %in% loadedNamespaces()) + unloadNamespace("renv") + + # load bootstrap tools + `%||%` <- function(x, y) { + if (is.environment(x) || length(x)) x else y + } + + bootstrap <- function(version, library) { + + # attempt to download renv + tarball <- tryCatch(renv_bootstrap_download(version), error = identity) + if (inherits(tarball, "error")) + stop("failed to download renv ", version) + + # now attempt to install + status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity) + if (inherits(status, "error")) + stop("failed to install renv ", version) + + } + + renv_bootstrap_tests_running <- function() { + getOption("renv.tests.running", default = FALSE) + } + + renv_bootstrap_repos <- function() { + + # check for repos override + repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA) + if (!is.na(repos)) + return(repos) + + # check for lockfile repositories + repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity) + if (!inherits(repos, "error") && length(repos)) + return(repos) + + # if we're testing, re-use the test repositories + if (renv_bootstrap_tests_running()) + return(getOption("renv.tests.repos")) + + # retrieve current repos + repos <- getOption("repos") + + # ensure @CRAN@ entries are resolved + repos[repos == "@CRAN@"] <- getOption( + "renv.repos.cran", + "https://cloud.r-project.org" + ) + + # add in renv.bootstrap.repos if set + default <- c(FALLBACK = "https://cloud.r-project.org") + extra <- getOption("renv.bootstrap.repos", default = default) + repos <- c(repos, extra) + + # remove duplicates that might've snuck in + dupes <- duplicated(repos) | duplicated(names(repos)) + repos[!dupes] + + } + + renv_bootstrap_repos_lockfile <- function() { + + lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock") + if (!file.exists(lockpath)) + return(NULL) + + lockfile <- tryCatch(renv_json_read(lockpath), error = identity) + if (inherits(lockfile, "error")) { + warning(lockfile) + return(NULL) + } + + repos <- lockfile$R$Repositories + if (length(repos) == 0) + return(NULL) + + keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1)) + vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1)) + names(vals) <- keys + + return(vals) + + } + + renv_bootstrap_download <- function(version) { + + # if the renv version number has 4 components, assume it must + # be retrieved via github + nv <- numeric_version(version) + components <- unclass(nv)[[1]] + + # if this appears to be a development version of 'renv', we'll + # try to restore from github + dev <- length(components) == 4L + + # begin collecting different methods for finding renv + methods <- c( + renv_bootstrap_download_tarball, + if (dev) + renv_bootstrap_download_github + else c( + renv_bootstrap_download_cran_latest, + renv_bootstrap_download_cran_archive + ) + ) + + for (method in methods) { + path <- tryCatch(method(version), error = identity) + if (is.character(path) && file.exists(path)) + return(path) + } + + stop("failed to download renv ", version) + + } + + renv_bootstrap_download_impl <- function(url, destfile) { + + mode <- "wb" + + # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715 + fixup <- + Sys.info()[["sysname"]] == "Windows" && + substring(url, 1L, 5L) == "file:" + + if (fixup) + mode <- "w+b" + + args <- list( + url = url, + destfile = destfile, + mode = mode, + quiet = TRUE + ) + + if ("headers" %in% names(formals(utils::download.file))) + args$headers <- renv_bootstrap_download_custom_headers(url) + + do.call(utils::download.file, args) + + } + + renv_bootstrap_download_custom_headers <- function(url) { + + headers <- getOption("renv.download.headers") + if (is.null(headers)) + return(character()) + + if (!is.function(headers)) + stopf("'renv.download.headers' is not a function") + + headers <- headers(url) + if (length(headers) == 0L) + return(character()) + + if (is.list(headers)) + headers <- unlist(headers, recursive = FALSE, use.names = TRUE) + + ok <- + is.character(headers) && + is.character(names(headers)) && + all(nzchar(names(headers))) + + if (!ok) + stop("invocation of 'renv.download.headers' did not return a named character vector") + + headers + + } + + renv_bootstrap_download_cran_latest <- function(version) { + + spec <- renv_bootstrap_download_cran_latest_find(version) + type <- spec$type + repos <- spec$repos + + message("* Downloading renv ", version, " ... ", appendLF = FALSE) + + baseurl <- utils::contrib.url(repos = repos, type = type) + ext <- if (identical(type, "source")) + ".tar.gz" + else if (Sys.info()[["sysname"]] == "Windows") + ".zip" + else + ".tgz" + name <- sprintf("renv_%s%s", version, ext) + url <- paste(baseurl, name, sep = "/") + + destfile <- file.path(tempdir(), name) + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (inherits(status, "condition")) { + message("FAILED") + return(FALSE) + } + + # report success and return + message("OK (downloaded ", type, ")") + destfile + + } + + renv_bootstrap_download_cran_latest_find <- function(version) { + + # check whether binaries are supported on this system + binary <- + getOption("renv.bootstrap.binary", default = TRUE) && + !identical(.Platform$pkgType, "source") && + !identical(getOption("pkgType"), "source") && + Sys.info()[["sysname"]] %in% c("Darwin", "Windows") + + types <- c(if (binary) "binary", "source") + + # iterate over types + repositories + for (type in types) { + for (repos in renv_bootstrap_repos()) { + + # retrieve package database + db <- tryCatch( + as.data.frame( + utils::available.packages(type = type, repos = repos), + stringsAsFactors = FALSE + ), + error = identity + ) + + if (inherits(db, "error")) + next + + # check for compatible entry + entry <- db[db$Package %in% "renv" & db$Version %in% version, ] + if (nrow(entry) == 0) + next + + # found it; return spec to caller + spec <- list(entry = entry, type = type, repos = repos) + return(spec) + + } + } + + # if we got here, we failed to find renv + fmt <- "renv %s is not available from your declared package repositories" + stop(sprintf(fmt, version)) + + } + + renv_bootstrap_download_cran_archive <- function(version) { + + name <- sprintf("renv_%s.tar.gz", version) + repos <- renv_bootstrap_repos() + urls <- file.path(repos, "src/contrib/Archive/renv", name) + destfile <- file.path(tempdir(), name) + + message("* Downloading renv ", version, " ... ", appendLF = FALSE) + + for (url in urls) { + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (identical(status, 0L)) { + message("OK") + return(destfile) + } + + } + + message("FAILED") + return(FALSE) + + } + + renv_bootstrap_download_tarball <- function(version) { + + # if the user has provided the path to a tarball via + # an environment variable, then use it + tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA) + if (is.na(tarball)) + return() + + # allow directories + info <- file.info(tarball, extra_cols = FALSE) + if (identical(info$isdir, TRUE)) { + name <- sprintf("renv_%s.tar.gz", version) + tarball <- file.path(tarball, name) + } + + # bail if it doesn't exist + if (!file.exists(tarball)) { + + # let the user know we weren't able to honour their request + fmt <- "* RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." + msg <- sprintf(fmt, tarball) + warning(msg) + + # bail + return() + + } + + fmt <- "* Bootstrapping with tarball at path '%s'." + msg <- sprintf(fmt, tarball) + message(msg) + + tarball + + } + + renv_bootstrap_download_github <- function(version) { + + enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") + if (!identical(enabled, "TRUE")) + return(FALSE) + + # prepare download options + pat <- Sys.getenv("GITHUB_PAT") + if (nzchar(Sys.which("curl")) && nzchar(pat)) { + fmt <- "--location --fail --header \"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "curl", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + fmt <- "--header=\"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "wget", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } + + message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE) + + url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) + name <- sprintf("renv_%s.tar.gz", version) + destfile <- file.path(tempdir(), name) + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (!identical(status, 0L)) { + message("FAILED") + return(FALSE) + } + + message("OK") + return(destfile) + + } + + renv_bootstrap_install <- function(version, tarball, library) { + + # attempt to install it into project library + message("* Installing renv ", version, " ... ", appendLF = FALSE) + dir.create(library, showWarnings = FALSE, recursive = TRUE) + + # invoke using system2 so we can capture and report output + bin <- R.home("bin") + exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" + r <- file.path(bin, exe) + + args <- c( + "--vanilla", "CMD", "INSTALL", "--no-multiarch", + "-l", shQuote(path.expand(library)), + shQuote(path.expand(tarball)) + ) + + output <- system2(r, args, stdout = TRUE, stderr = TRUE) + message("Done!") + + # check for successful install + status <- attr(output, "status") + if (is.numeric(status) && !identical(status, 0L)) { + header <- "Error installing renv:" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- c(header, lines, output) + writeLines(text, con = stderr()) + } + + status + + } + + renv_bootstrap_platform_prefix <- function() { + + # construct version prefix + version <- paste(R.version$major, R.version$minor, sep = ".") + prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") + + # include SVN revision for development versions of R + # (to avoid sharing platform-specific artefacts with released versions of R) + devel <- + identical(R.version[["status"]], "Under development (unstable)") || + identical(R.version[["nickname"]], "Unsuffered Consequences") + + if (devel) + prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") + + # build list of path components + components <- c(prefix, R.version$platform) + + # include prefix if provided by user + prefix <- renv_bootstrap_platform_prefix_impl() + if (!is.na(prefix) && nzchar(prefix)) + components <- c(prefix, components) + + # build prefix + paste(components, collapse = "/") + + } + + renv_bootstrap_platform_prefix_impl <- function() { + + # if an explicit prefix has been supplied, use it + prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA) + if (!is.na(prefix)) + return(prefix) + + # if the user has requested an automatic prefix, generate it + auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (auto %in% c("TRUE", "True", "true", "1")) + return(renv_bootstrap_platform_prefix_auto()) + + # empty string on failure + "" + + } + + renv_bootstrap_platform_prefix_auto <- function() { + + prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity) + if (inherits(prefix, "error") || prefix %in% "unknown") { + + msg <- paste( + "failed to infer current operating system", + "please file a bug report at https://github.com/rstudio/renv/issues", + sep = "; " + ) + + warning(msg) + + } + + prefix + + } + + renv_bootstrap_platform_os <- function() { + + sysinfo <- Sys.info() + sysname <- sysinfo[["sysname"]] + + # handle Windows + macOS up front + if (sysname == "Windows") + return("windows") + else if (sysname == "Darwin") + return("macos") + + # check for os-release files + for (file in c("/etc/os-release", "/usr/lib/os-release")) + if (file.exists(file)) + return(renv_bootstrap_platform_os_via_os_release(file, sysinfo)) + + # check for redhat-release files + if (file.exists("/etc/redhat-release")) + return(renv_bootstrap_platform_os_via_redhat_release()) + + "unknown" + + } + + renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) { + + # read /etc/os-release + release <- utils::read.table( + file = file, + sep = "=", + quote = c("\"", "'"), + col.names = c("Key", "Value"), + comment.char = "#", + stringsAsFactors = FALSE + ) + + vars <- as.list(release$Value) + names(vars) <- release$Key + + # get os name + os <- tolower(sysinfo[["sysname"]]) + + # read id + id <- "unknown" + for (field in c("ID", "ID_LIKE")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + id <- vars[[field]] + break + } + } + + # read version + version <- "unknown" + for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + version <- vars[[field]] + break + } + } + + # join together + paste(c(os, id, version), collapse = "-") + + } + + renv_bootstrap_platform_os_via_redhat_release <- function() { + + # read /etc/redhat-release + contents <- readLines("/etc/redhat-release", warn = FALSE) + + # infer id + id <- if (grepl("centos", contents, ignore.case = TRUE)) + "centos" + else if (grepl("redhat", contents, ignore.case = TRUE)) + "redhat" + else + "unknown" + + # try to find a version component (very hacky) + version <- "unknown" + + parts <- strsplit(contents, "[[:space:]]")[[1L]] + for (part in parts) { + + nv <- tryCatch(numeric_version(part), error = identity) + if (inherits(nv, "error")) + next + + version <- nv[1, 1] + break + + } + + paste(c("linux", id, version), collapse = "-") + + } + + renv_bootstrap_library_root_name <- function(project) { + + # use project name as-is if requested + asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE") + if (asis) + return(basename(project)) + + # otherwise, disambiguate based on project's path + id <- substring(renv_bootstrap_hash_text(project), 1L, 8L) + paste(basename(project), id, sep = "-") + + } + + renv_bootstrap_library_root <- function(project) { + + prefix <- renv_bootstrap_profile_prefix() + + path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA) + if (!is.na(path)) + return(paste(c(path, prefix), collapse = "/")) + + path <- renv_bootstrap_library_root_impl(project) + if (!is.null(path)) { + name <- renv_bootstrap_library_root_name(project) + return(paste(c(path, prefix, name), collapse = "/")) + } + + renv_bootstrap_paths_renv("library", project = project) + + } + + renv_bootstrap_library_root_impl <- function(project) { + + root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA) + if (!is.na(root)) + return(root) + + type <- renv_bootstrap_project_type(project) + if (identical(type, "package")) { + userdir <- renv_bootstrap_user_dir() + return(file.path(userdir, "library")) + } + + } + + renv_bootstrap_validate_version <- function(version) { + + loadedversion <- utils::packageDescription("renv", fields = "Version") + if (version == loadedversion) + return(TRUE) + + # assume four-component versions are from GitHub; three-component + # versions are from CRAN + components <- strsplit(loadedversion, "[.-]")[[1]] + remote <- if (length(components) == 4L) + paste("rstudio/renv", loadedversion, sep = "@") + else + paste("renv", loadedversion, sep = "@") + + fmt <- paste( + "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", + "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", + "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", + sep = "\n" + ) + + msg <- sprintf(fmt, loadedversion, version, remote) + warning(msg, call. = FALSE) + + FALSE + + } + + renv_bootstrap_hash_text <- function(text) { + + hashfile <- tempfile("renv-hash-") + on.exit(unlink(hashfile), add = TRUE) + + writeLines(text, con = hashfile) + tools::md5sum(hashfile) + + } + + renv_bootstrap_load <- function(project, libpath, version) { + + # try to load renv from the project library + if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) + return(FALSE) + + # warn if the version of renv loaded does not match + renv_bootstrap_validate_version(version) + + # load the project + renv::load(project) + + TRUE + + } + + renv_bootstrap_profile_load <- function(project) { + + # if RENV_PROFILE is already set, just use that + profile <- Sys.getenv("RENV_PROFILE", unset = NA) + if (!is.na(profile) && nzchar(profile)) + return(profile) + + # check for a profile file (nothing to do if it doesn't exist) + path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project) + if (!file.exists(path)) + return(NULL) + + # read the profile, and set it if it exists + contents <- readLines(path, warn = FALSE) + if (length(contents) == 0L) + return(NULL) + + # set RENV_PROFILE + profile <- contents[[1L]] + if (!profile %in% c("", "default")) + Sys.setenv(RENV_PROFILE = profile) + + profile + + } + + renv_bootstrap_profile_prefix <- function() { + profile <- renv_bootstrap_profile_get() + if (!is.null(profile)) + return(file.path("profiles", profile, "renv")) + } + + renv_bootstrap_profile_get <- function() { + profile <- Sys.getenv("RENV_PROFILE", unset = "") + renv_bootstrap_profile_normalize(profile) + } + + renv_bootstrap_profile_set <- function(profile) { + profile <- renv_bootstrap_profile_normalize(profile) + if (is.null(profile)) + Sys.unsetenv("RENV_PROFILE") + else + Sys.setenv(RENV_PROFILE = profile) + } + + renv_bootstrap_profile_normalize <- function(profile) { + + if (is.null(profile) || profile %in% c("", "default")) + return(NULL) + + profile + + } + + renv_bootstrap_path_absolute <- function(path) { + + substr(path, 1L, 1L) %in% c("~", "/", "\\") || ( + substr(path, 1L, 1L) %in% c(letters, LETTERS) && + substr(path, 2L, 3L) %in% c(":/", ":\\") + ) + + } + + renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) { + renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv") + root <- if (renv_bootstrap_path_absolute(renv)) NULL else project + prefix <- if (profile) renv_bootstrap_profile_prefix() + components <- c(root, renv, prefix, ...) + paste(components, collapse = "/") + } + + renv_bootstrap_project_type <- function(path) { + + descpath <- file.path(path, "DESCRIPTION") + if (!file.exists(descpath)) + return("unknown") + + desc <- tryCatch( + read.dcf(descpath, all = TRUE), + error = identity + ) + + if (inherits(desc, "error")) + return("unknown") + + type <- desc$Type + if (!is.null(type)) + return(tolower(type)) + + package <- desc$Package + if (!is.null(package)) + return("package") + + "unknown" + + } + + renv_bootstrap_user_dir <- function() { + dir <- renv_bootstrap_user_dir_impl() + path.expand(chartr("\\", "/", dir)) + } + + renv_bootstrap_user_dir_impl <- function() { + + # use local override if set + override <- getOption("renv.userdir.override") + if (!is.null(override)) + return(override) + + # use R_user_dir if available + tools <- asNamespace("tools") + if (is.function(tools$R_user_dir)) + return(tools$R_user_dir("renv", "cache")) + + # try using our own backfill for older versions of R + envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME") + for (envvar in envvars) { + root <- Sys.getenv(envvar, unset = NA) + if (!is.na(root)) + return(file.path(root, "R/renv")) + } + + # use platform-specific default fallbacks + if (Sys.info()[["sysname"]] == "Windows") + file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv") + else if (Sys.info()[["sysname"]] == "Darwin") + "~/Library/Caches/org.R-project.R/R/renv" + else + "~/.cache/R/renv" + + } + + + renv_json_read <- function(file = NULL, text = NULL) { + + # if jsonlite is loaded, use that instead + if ("jsonlite" %in% loadedNamespaces()) + renv_json_read_jsonlite(file, text) + else + renv_json_read_default(file, text) + + } + + renv_json_read_jsonlite <- function(file = NULL, text = NULL) { + text <- paste(text %||% read(file), collapse = "\n") + jsonlite::fromJSON(txt = text, simplifyVector = FALSE) + } + + renv_json_read_default <- function(file = NULL, text = NULL) { + + # find strings in the JSON + text <- paste(text %||% read(file), collapse = "\n") + pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + locs <- gregexpr(pattern, text, perl = TRUE)[[1]] + + # if any are found, replace them with placeholders + replaced <- text + strings <- character() + replacements <- character() + + if (!identical(c(locs), -1L)) { + + # get the string values + starts <- locs + ends <- locs + attr(locs, "match.length") - 1L + strings <- substring(text, starts, ends) + + # only keep those requiring escaping + strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE) + + # compute replacements + replacements <- sprintf('"\032%i\032"', seq_along(strings)) + + # replace the strings + mapply(function(string, replacement) { + replaced <<- sub(string, replacement, replaced, fixed = TRUE) + }, strings, replacements) + + } + + # transform the JSON into something the R parser understands + transformed <- replaced + transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) + transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) + transformed <- gsub("[]}]", ")", transformed, perl = TRUE) + transformed <- gsub(":", "=", transformed, fixed = TRUE) + text <- paste(transformed, collapse = "\n") + + # parse it + json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]] + + # construct map between source strings, replaced strings + map <- as.character(parse(text = strings)) + names(map) <- as.character(parse(text = replacements)) + + # convert to list + map <- as.list(map) + + # remap strings in object + remapped <- renv_json_remap(json, map) + + # evaluate + eval(remapped, envir = baseenv()) + + } + + renv_json_remap <- function(json, map) { + + # fix names + if (!is.null(names(json))) { + lhs <- match(names(json), names(map), nomatch = 0L) + rhs <- match(names(map), names(json), nomatch = 0L) + names(json)[rhs] <- map[lhs] + } + + # fix values + if (is.character(json)) + return(map[[json]] %||% json) + + # handle true, false, null + if (is.name(json)) { + text <- as.character(json) + if (text == "true") + return(TRUE) + else if (text == "false") + return(FALSE) + else if (text == "null") + return(NULL) + } + + # recurse + if (is.recursive(json)) { + for (i in seq_along(json)) { + json[i] <- list(renv_json_remap(json[[i]], map)) + } + } + + json + + } + + # load the renv profile, if any + renv_bootstrap_profile_load(project) + + # construct path to library root + root <- renv_bootstrap_library_root(project) + + # construct library prefix for platform + prefix <- renv_bootstrap_platform_prefix() + + # construct full libpath + libpath <- file.path(root, prefix) + + # attempt to load + if (renv_bootstrap_load(project, libpath, version)) + return(TRUE) + + # load failed; inform user we're about to bootstrap + prefix <- paste("# Bootstrapping renv", version) + postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "") + header <- paste(prefix, postfix) + message(header) + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + message("* Successfully installed and loaded renv ", version, ".") + return(renv::load()) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) + + warning(paste(msg, collapse = "\n"), call. = FALSE) + +}) diff --git a/renv/settings.dcf b/renv/settings.dcf new file mode 100644 index 0000000..169d82f --- /dev/null +++ b/renv/settings.dcf @@ -0,0 +1,10 @@ +bioconductor.version: +external.libraries: +ignored.packages: +package.dependency.fields: Imports, Depends, LinkingTo +r.version: +snapshot.type: implicit +use.cache: TRUE +vcs.ignore.cellar: TRUE +vcs.ignore.library: TRUE +vcs.ignore.local: TRUE diff --git a/test/.DS_Store b/test/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/test/.DS_Store differ diff --git a/test/my_address_file_geocoded.csv b/test/my_address_file_geocoded.csv new file mode 100644 index 0000000..8e2e81f --- /dev/null +++ b/test/my_address_file_geocoded.csv @@ -0,0 +1,4 @@ +id,lat,lon,start_date,end_date +1,34.41471040449594,-115.04499837139416,2008-01-21,2008-01-27 +2,34.02192926572527,-116.056401323031,2008-01-28,2008-02-03 +3,35.22267356636723,-118.54506279596853,2008-01-25,2008-01-31 diff --git a/test/my_address_file_geocoded_habre_pm_0.1.0.csv b/test/my_address_file_geocoded_habre_pm_0.1.0.csv new file mode 100644 index 0000000..34f1212 --- /dev/null +++ b/test/my_address_file_geocoded_habre_pm_0.1.0.csv @@ -0,0 +1,4 @@ +id,lat,lon,start_date,end_date,pm,sd +1,34.41471040449594,-115.04499837139416,2008-01-21,2008-01-27,4.05,2.67 +2,34.02192926572527,-116.056401323031,2008-01-28,2008-02-03,3.55,1.65 +3,35.22267356636723,-118.54506279596852,2008-01-25,2008-01-31,5.8,1.61