Skip to content

Commit f352233

Browse files
authored
Merge pull request #29 from AgroCares/addvignette
Addvignette
2 parents d8a0206 + bd519c9 commit f352233

9 files changed

+1157
-16
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ vignettes/*.pdf
3737

3838
# R Environment Variables
3939
.Renviron
40+
inst/doc

Diff for: DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: soilptf
22
Type: Package
33
Title: Estimate soil properties via pedotransferfunctions
4-
Version: 0.4.1
4+
Version: 0.5.0.9000
55
Authors@R: c(person(given = "Gerard", family = "Ros", email = "[email protected]", role = c("aut","cre")),
66
person(given = "Kees", family = "van den Dool", email = "[email protected]", role = c("aut")),
77
person(given = "Sven", family = "Verweij", email = "[email protected]", role = c("aut")),

Diff for: NEWS.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog soilptf
22

3+
## Version 0.5.0 2023-04-29
4+
5+
## Added
6+
* add vignette `how to contribute`
7+
* add vignette `introduction`
8+
9+
## Fixed
10+
* add missing id in wrapper functions `ptf_xxx_all'
11+
* add mineralogy check in `sptf_textureclass` and replace missing input when 2 of the 3 inputs are known.
12+
313
## Version 0.4.1 2023-04-29
414

515
### Fixed

Diff for: R/erodibility.R

+1
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,4 @@ sptf_erodibility2 <- function(A_CLAY_MI,A_SILT_MI,A_C_OF) {
8585

8686
}
8787

88+
# see also rakkar_2019

Diff for: R/sptf_predict.R

+49-13
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,13 @@ ptf_bd_all <- function(dt){
380380
num_obs = A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_H20_T105 = NULL
381381
A_DEPTH = B_ALTITUDE = B_SLOPE_DEGREE = B_SLOPE_ASPECT = A_PH_WA = A_CACO3_IF = NULL
382382
A_N_RT = A_SAND_M50 = A_H2O_T105 = ptf_id = patterns = NULL
383-
A_PH_KCL = A_PH_CC = B_LU_PTFCLASS = NULL
383+
A_PH_KCL = A_PH_CC = id = B_LU_PTFCLASS = NULL
384384

385385
dt <- copy(dt)
386-
386+
387+
# add id (as row number) when its not available
388+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
389+
387390
# add all possible inputs as NA when missing
388391
cols <- c('A_CLAY_MI','A_SAND_MI','A_SILT_MI', 'A_C_OF', 'A_DEPTH','A_SOM_LOI',
389392
'A_PH_WA','A_CACO3_IF','A_N_RT','A_H2O_T105','A_SAND_M50',
@@ -858,12 +861,15 @@ ptf_whc_all <- function(dt){
858861
p15 = p16 = A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_H20_T105 = NULL
859862
A_DEPTH = B_ALTITUDE = B_SLOPE_DEGREE = B_SLOPE_ASPECT = A_PH_WA = A_CACO3_IF = NULL
860863
A_N_RT = A_SAND_M50 = B_SOILTYPE_AGR = D_BDS = topsoil = NULL
861-
patterns = ptf_id = country_code = continent_code = . = ptf_id = nsample = r2 = NULL
864+
patterns = ptf_id =id = country_code = continent_code = . = ptf_id = nsample = r2 = NULL
862865
nrep = value = error = patterns = num_obs = whc = NULL
863866

864867
# make local copy
865868
dt <- copy(dt)
866869

870+
# add id (as row number) when its not available
871+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
872+
867873
# add all possible inputs as NA when missing
868874
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_CLAY_MI','A_SAND_MI','A_SILT_MI', 'D_BDS',
869875
'A_DEPTH', 'topsoil')
@@ -1070,12 +1076,15 @@ ptf_paw_all <- function(dt){
10701076
p15 = p16 = A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_H20_T105 = NULL
10711077
A_DEPTH = B_ALTITUDE = B_SLOPE_DEGREE = B_SLOPE_ASPECT = A_PH_WA = A_CACO3_IF = NULL
10721078
A_N_RT = A_SAND_M50 = B_SOILTYPE_AGR = D_BDS = topsoil = NULL
1073-
patterns = ptf_id = country_code = continent_code = . = ptf_id = nsample = r2 = NULL
1079+
patterns = ptf_id = id = country_code = continent_code = . = ptf_id = nsample = r2 = NULL
10741080
nrep = value = error = patterns = num_obs = paw = NULL
10751081

10761082
# make local copy
10771083
dt <- copy(dt)
10781084

1085+
# add id (as row number) when its not available
1086+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
1087+
10791088
# add all possible inputs as NA when missing
10801089
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_CLAY_MI','A_SAND_MI','A_SILT_MI', 'D_BDS',
10811090
'A_DEPTH', 'topsoil')
@@ -1282,11 +1291,14 @@ ptf_cec_all <- function(dt){
12821291
p63 = p64 = p65 = p66 = p67 = p68 = p69 = p70 = p71 = p72 = p73 = p74 = NULL
12831292
p75 = NULL
12841293
num_obs = A_CACO3_MI = A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_PH_KCL = A_PH_CC = A_PH_WA = NULL
1285-
B_LU_PTFCLASS = A_CN_FR = B_SOILCLASS_USDA = B_CLIM_CAT1 = patterns = ptf_id = cec = NULL
1294+
B_LU_PTFCLASS = id = A_CN_FR = B_SOILCLASS_USDA = B_CLIM_CAT1 = patterns = ptf_id = cec = NULL
12861295

12871296
# make local copy
12881297
dt <- copy(dt)
12891298

1299+
# add id (as row number) when its not available
1300+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
1301+
12901302
# add all numeric inputs as NA when missing
12911303
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_CLAY_MI','A_SAND_MI','A_SILT_MI',
12921304
'A_CACO3_MI','A_PH_KCL','A_PH_CC','A_PH_WA','A_CN_FR')
@@ -1548,11 +1560,14 @@ ptf_phbc_all <- function(dt){
15481560
# add visual binding
15491561
p1 = p2 = p3 = p4 = p5 = p6 = p7 = p8 = NULL
15501562
A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_PH_KCL = A_PH_WA = A_PH_CC = NULL
1551-
num_obs = patterns = ptf_id = phbc = NULL
1563+
num_obs = patterns = ptf_id = id = phbc = NULL
15521564

15531565
# make local copy
15541566
dt <- copy(dt)
15551567

1568+
# add id (as row number) when its not available
1569+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
1570+
15561571
# add all possible inputs as NA when missing
15571572
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_CLAY_MI','A_PH_WA','A_SAND_MI','A_SILT_MI','A_PH_KCL','A_PH_CC')
15581573
cols <- cols[!cols %in% colnames(dt)]
@@ -1737,12 +1752,15 @@ ptf_mwd_all <- function(dt){
17371752
# add visual binding
17381753
p1 = p2 = p3 = p4 = p5 = p6 = p7 = p8 = p9 = p10 = p11 = p12 = p13 = p14 = p15 = NULL
17391754
A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_PH_KCL = A_PH_WA = A_PH_CC = NULL
1740-
num_obs = patterns = ptf_id = mwd = NULL
1755+
num_obs = patterns = ptf_id = id = mwd = NULL
17411756
B_LU_PTFCLASS = A_CEC_CO = A_CACO3_MI = NULL
17421757

17431758
# make local copy
17441759
dt <- copy(dt)
17451760

1761+
# add id (as row number) when its not available
1762+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
1763+
17461764
# add all possible numeric inputs as NA when missing
17471765
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_CLAY_MI','A_SAND_MI','A_SILT_MI',
17481766
'A_CEC_CO','A_CACO3_MI','A_PH_WA','A_PH_KCL','A_PH_CC')
@@ -1941,13 +1959,16 @@ ptf_wsa_all <- function(dt){
19411959

19421960
# add visual binding
19431961
p1 = p2 = p3 = p4 = p5 = p6 = p7 = p8 = p9 = patterns = NULL
1944-
patterns = num_obs = ptf_id = wsa = NULL
1962+
patterns = num_obs = ptf_id = id = wsa = NULL
19451963
A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_PH_KCL = A_PH_WA = A_PH_CC = NULL
19461964
A_K_AA = A_CACO3_MI = NULL
19471965

19481966
# make local copy
19491967
dt <- copy(dt)
19501968

1969+
# add id (as row number) when its not available
1970+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
1971+
19511972
# add all possible inputs as NA when missing
19521973
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_CLAY_MI','A_SAND_MI','A_SILT_MI',
19531974
'A_CACO3_MI','A_PH_WA','A_K_AA','A_PH_KCL','A_PH_CC')
@@ -2137,11 +2158,14 @@ ptf_hwc_all <- function(dt){
21372158
# add visual binding
21382159
p1 = p2 = p3 = p4 = p5 = p6 = p7 = p8 = p9 = p10 = p11 = NULL
21392160
A_P_AL = A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_PH_KCL = A_PH_WA = A_PH_CC = NULL
2140-
num_obs = patterns = ptf_id = hwc = NULL
2161+
num_obs = patterns = ptf_id = id = hwc = NULL
21412162

21422163
# make local copy
21432164
dt <- copy(dt)
21442165

2166+
# add id (as row number) when its not available
2167+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
2168+
21452169
# add all possible inputs as NA when missing
21462170
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_CLAY_MI','A_SAND_MI','A_SILT_MI','A_PH_CC','A_P_AL',
21472171
'A_PH_KCL','A_PH_WA')
@@ -2335,11 +2359,14 @@ ptf_sss_all <- function(dt){
23352359
# add visual binding
23362360
p1 = p2 = p3 = NULL
23372361
A_CACO3_MI = A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_PH_KCL = A_PH_WA = A_PH_CC = NULL
2338-
num_obs = patterns = ptf_id = sss = NULL
2362+
num_obs = patterns = ptf_id = id = sss = NULL
23392363

23402364
# make local copy
23412365
dt <- copy(dt)
23422366

2367+
# add id (as row number) when its not available
2368+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
2369+
23432370
# add all possible inputs as NA when missing
23442371
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_CLAY_MI','A_SAND_MI','A_SILT_MI','A_CACO3_MI')
23452372
cols <- cols[!cols %in% colnames(dt)]
@@ -2519,11 +2546,14 @@ ptf_metals_all <- function(dt){
25192546
# add visual binding
25202547
p1 = p2 = p3 = p4 = NULL
25212548
A_CLAY_MI = A_SAND_MI = A_SILT_MI = A_SOM_LOI = A_C_OF = A_PH_KCL = A_PH_WA = A_PH_CC = NULL
2522-
num_obs = patterns = ptf_id = metal = NULL
2549+
num_obs = patterns = ptf_id = id = metal = NULL
25232550

25242551
# make local copy
25252552
dt <- copy(dt)
25262553

2554+
# add id (as row number) when its not available
2555+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
2556+
25272557
# add all possible inputs as NA when missing
25282558
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_CLAY_MI','A_SAND_MI','A_SILT_MI','A_CACO3_MI',
25292559
'A_PH_WA','A_PH_CC','A_PH_KCL')
@@ -2711,11 +2741,14 @@ ptf_metals <- function(A_SOM_LOI = NA_real_, A_C_OF = NA_real_,
27112741
ptf_cdec_all <- function(dt){
27122742

27132743
# add visual binding
2714-
A_C_OF = A_SOM_LOI = A_N_RT = patterns = ptf_id = cdec = p1 = NULL
2744+
A_C_OF = A_SOM_LOI = A_N_RT = patterns = ptf_id = id = cdec = p1 = NULL
27152745

27162746
# make local copy
27172747
dt <- copy(dt)
27182748

2749+
# add id (as row number) when its not available
2750+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
2751+
27192752
# add all possible inputs as NA when missing
27202753
cols <- c('A_SOM_LOI', 'A_C_OF', 'A_N_RT')
27212754
cols <- cols[!cols %in% colnames(dt)]
@@ -2891,11 +2924,14 @@ ptf_pmn_all <- function(dt){
28912924
A_PH_KCL = A_PH_WA = A_PH_CC= pmn = A_P_AL = NULL
28922925
num_obs = A_SOM_LOI = p1_p = p1 = p2 = p3 = p4 = p5 = p6 = p7 = p8 = p9 = p10 = NULL
28932926
p11 = p12 = p13 = p14 = p15 = p16 = p17 = p18 = p19 = NULL
2894-
patterns = ptf_id = NULL
2927+
patterns = ptf_id = id = NULL
28952928

28962929
# make local copy
28972930
dt <- copy(dt)
28982931

2932+
# add id (as row number) when its not available
2933+
if(!'id' %in% colnames(dt)){dt[,id := 1:.N]}
2934+
28992935
# add all possible inputs as NA when missing
29002936
cols <- c('A_C_OF','A_SOM_LOI', 'A_CLAY_MI','A_SAND_MI','A_SILT_MI',
29012937
'A_N_RT', 'A_PH_CC', 'A_CEC_CO','A_P_AL','A_PH_KCL','A_PH_WA')

Diff for: R/sptf_textureclass.R

+8-2
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,27 @@
88
sptf_textureclass <- function(A_CLAY_MI, A_SILT_MI, A_SAND_MI){
99

1010
# add visual bindings
11-
cl = sa = si = NULL
11+
cl = sa = si = num_obs = NULL
1212

1313
# check inputs
1414
arg.length <- max(length(A_CLAY_MI),length(A_SAND_MI),length(A_SILT_MI))
1515
checkmate::assert_numeric(A_CLAY_MI, lower = 0, upper = 100, len = arg.length)
1616
checkmate::assert_numeric(A_SAND_MI, lower = 0, upper = 100, len = arg.length)
1717
checkmate::assert_numeric(A_SILT_MI, lower = 0, upper = 100, len = arg.length)
18-
checkmate::assert_true(all(rowSums(data.table(A_CLAY_MI, A_SAND_MI, A_SILT_MI)) <= 100))
18+
checkmate::assert_true(all(rowSums(data.table(A_CLAY_MI, A_SAND_MI, A_SILT_MI),na.rm=T) <= 100))
1919

2020
# make internal table with shorter names
2121
dt <- data.table(cl = A_CLAY_MI,
2222
sa = A_SAND_MI,
2323
si = A_SILT_MI,
2424
value = NA_character_)
2525

26+
# estimate missing variables for texture being dependent on each other
27+
dt[, num_obs := Reduce(`+`, lapply(.SD,function(x) !is.na(x))),.SDcols = c('cl','sa','si')]
28+
dt[num_obs == 2 & is.na(cl), cl := 100 - sa - si]
29+
dt[num_obs == 2 & is.na(sa), sa := 100 - cl - si]
30+
dt[num_obs == 2 & is.na(si), si := 100 - cl - sa]
31+
2632
# find USDA classification
2733
dt[cl>40 & sa <=45 & si<=40, value := 'clay']
2834
dt[cl>40 & sa <=20 & si<=60 & si>40, value := 'silty clay']

Diff for: vignettes/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.html
2+
*.R

Diff for: vignettes/howtocontribute.Rmd

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: "how to contribute?"
3+
output: rmarkdown::html_vignette
4+
vignette: >
5+
%\VignetteIndexEntry{how to contribute?}
6+
%\VignetteEngine{knitr::rmarkdown}
7+
%\VignetteEncoding{UTF-8}
8+
---
9+
10+
```{r, include = FALSE}
11+
knitr::opts_chunk$set(
12+
collapse = TRUE,
13+
comment = "#>"
14+
)
15+
```
16+
17+
```{r setup}
18+
library(soilptf)
19+
```
20+
21+
# Introduction
22+
The soilptf package contains a series of pedotransferfunctions to assess soil functions and soil health indicactors.Depending on basic criteria for their applicability, you can apply them for each field or nature area. This guide explains the basic structure of this package and show how you can contribute by adding your own pedotransfer function.
23+
24+
The soilptf package has various ptfs for the following soil health indicators:
25+
* bulk density (bd)
26+
* hot water carbon (whc)
27+
* potentially mineralizable N (pmn)
28+
* cation exchange capacity (cec)
29+
* ph buffering capacity (phbc)
30+
* water stable aggregates (wsa)
31+
* mean weight diameter (mwd)
32+
* plant available water (paw), being the difference in moisture content for pF2 (field capacity) and pF4.2 (permanent wilting point)
33+
* water holding capacity (whc), the moisture content where the soil starts to saturate
34+
* soil shear strength (sss), determining the resistance to deformation by tangential (or shear) stress
35+
* threshold velocity (tv) for wind erosion
36+
* decomposition rate (dec)
37+
* metal buffering via freundlich coefficient (fc)
38+
39+
# the package structure
40+
41+
## package table with ptf properties
42+
All ptfs are summarized in the package tables `sptf_bulkdensity` and `sptf_soilproperties`. Over time both will be merged. The structure of these tables are defined in `R/sptf_tables.R`. Each ptf is described and categorized with the following properties: id, type, country, continent, soiltype, landuse, depth, nsample, r2, soilproperties (the desired input variables), the reference and the url where you can find te article describing the ptf.
43+
44+
## ptf function description
45+
All the individual ptfs are listed in a separate R script, given in the R directory. All functions follow the same structure:
46+
* the internal objects being used are set to NULL
47+
* internal checks are added on the function arguments using checkmate
48+
* add default properties if needed (optional) to enhance the applicability of the function, for example when soil properties are needed as input that are not generally available. in that case you replace the 'missing' one with the mean value of the dataset
49+
* combine all function arguments into an internal data.table dt
50+
* add the function(s) to calculate the soil health indicator or function
51+
* select the output variable (often called `value`) to be set as output of the function
52+
* return the output
53+
54+
## ptf wrapper function: predict all indicators
55+
For each soil health indicator or function there has been made a wrapper function that predicts the desired output for all the individual ptfs available in the package. Examples of these functions include `sptf_bd_all` for bulk density, `sptf_cec_all` for cec and `sptf_paw` for the plant available water. The output of these wrapper function is a datatable giving the predicted value by field_id for each of the individual ptfs. The structure is a tiny data.table.
56+
57+
Note that this wrapper function estimates relevant properties that 1-to-1 are correlated. For example, the soil organic matter level can be calculated from the soil organic carbon level (because they represent the same property), as well the soil mineralogy for sand, clay and silt if one of the elements is missing. This feature supports broad applicability without requesting all desired inputs to be added as required inputs in the functions.
58+
59+
## ptf predict function
60+
For each soil health indicator or function there is also a predict function that predicts the median value (plus standard deviation) of all the applicable soil ptfs. Examples of these functions include `sptf_bd` for bulk density and `sptf_cec` for the cation exchange capacity. These functions select the most relevant and approriate ptfs given the country, soil type, land use and depth and accounts for the differences in accuracy and reliability of the individual ptfs.
61+
62+
# How to contribute?
63+
64+
## Adding a new soil ptf for an existing soil health indicator
65+
If you want to add a new ptf you should take the following steps:
66+
67+
1. fork the repository for your addition
68+
2. update the package table `sptf_soilproperties`
69+
3. add the new ptf in the correct R script in directory `soilptf/R`
70+
4. expand the wrapper function in `soilptf/R/sptf_predict` with the new ptf
71+
5. add a test function in directory `soilptf/tests/testthat`
72+
6. do package checks
73+
7. update news and description file in `soilptf/R`
74+
8. create a pull request to merge your contribution
75+
76+
## Adding a new soil health indicator
77+
If you want to add a new soil health indicator or soil function you should take the following steps:
78+
79+
1. fork the repository for your addition
80+
2. update the package table `sptf_soilproperties` by adding a new ptf_type.
81+
3. add a new R script for the new soil health indicator in directory `soilptf/R`
82+
4. expand the wrapper function in `soilptf/R/sptf_predict` with a wrapper and a predict function.
83+
5. add relevant test function in directory `soilptf/tests/testthat`
84+
6. do package checks
85+
7. update news and description file in `soilptf/R`
86+
8. create a pull request to merge your contribution
87+
88+
## Data request
89+
In the coming years we aim to develop stochastic prediciton models that can be calibrated and validated on datasets with relevant soil properties. If you have relevant (published or unpublished) datasets that can be used, please add them as csv file to the `sptf/dev` directory.
90+
If you have particular datasets available that can be used as independent validation of the estimated soil health indicators, please contact the authors of this package.
91+
92+
# Others
93+
94+
## How to share ideas?
95+
If you detect errors or have ideas for nice additional features, you can add them in your own forked repo and ask for a pull request. If you are requesting a huge change in package structure or substantial update, please add / mark your request as issue on the sptf github page.
96+
97+
## Naming of soil properties as function arguments
98+
Function arguments, often being soil properties, have an unique name, being defined in the package table `sptf_parameters`. Each element (or soil properties) is defined with the given unit, the data type, the minimum and maximum allowed values (when numeric) or the allowed options (when categorial). The name of soil properties follow a unique combination of 1 to 4 elements such as `A_N_RT` that stands for the total nitrogen content of the soil In this name, the first position reflects the analysis type (A stands for soil properties, B for field properties, F voor feedstock properties), where the second position is related to the specific element (from the periodic table or any combination of them), the third position reflects the measurement method (eg. real total = RT, cacl2 extraction = CC, Cohex extraction = CO), and the last position might add specific methodological details that are needed to differentiate from the default. For example, the element `A_MG_CO` stands for the Mg content extracted with a Cohex extration, being the adsorbed Mg content of a soil (in units mmol+/kg), whereas `A_MG_CO_PO` refers to the same element but expresses the unit as percentage occupation (PO) of the cec. For your illustration, see the package table `sptf_parameters`
99+
100+

0 commit comments

Comments
 (0)