diff --git a/config.yaml b/config.yaml index ac99d9742..d22abc226 100644 --- a/config.yaml +++ b/config.yaml @@ -72,6 +72,7 @@ episodes: - 11-writing-data.Rmd - 12-dplyr.Rmd - 13-tidyr.Rmd +- statistics.Rmd - 14-knitr-markdown.Rmd - 15-wrap-up.Rmd diff --git a/episodes/fig/ContinuousDistribution.png b/episodes/fig/ContinuousDistribution.png deleted file mode 100644 index 51b2a951b..000000000 Binary files a/episodes/fig/ContinuousDistribution.png and /dev/null differ diff --git a/episodes/fig/HistogramAge.png b/episodes/fig/HistogramAge.png deleted file mode 100644 index c3a6556dd..000000000 Binary files a/episodes/fig/HistogramAge.png and /dev/null differ diff --git a/episodes/fig/HistogramHeight.png b/episodes/fig/HistogramHeight.png deleted file mode 100644 index 3c314ccf2..000000000 Binary files a/episodes/fig/HistogramHeight.png and /dev/null differ diff --git a/episodes/fig/IntervalData.png b/episodes/fig/IntervalData.png deleted file mode 100644 index 7663bee30..000000000 Binary files a/episodes/fig/IntervalData.png and /dev/null differ diff --git a/episodes/fig/NormalDistribution.png b/episodes/fig/NormalDistribution.png deleted file mode 100644 index 1688686b9..000000000 Binary files a/episodes/fig/NormalDistribution.png and /dev/null differ diff --git a/episodes/fig/OrdinalData.png b/episodes/fig/OrdinalData.png deleted file mode 100644 index 173569e6e..000000000 Binary files a/episodes/fig/OrdinalData.png and /dev/null differ diff --git a/episodes/fig/Test.png b/episodes/fig/Test.png deleted file mode 100644 index 1f9ee05ad..000000000 Binary files a/episodes/fig/Test.png and /dev/null differ diff --git a/episodes/fig/pValue.png b/episodes/fig/pValue.png deleted file mode 100644 index 66e3c669b..000000000 Binary files a/episodes/fig/pValue.png and /dev/null differ diff --git a/episodes/fig/pValue2.png b/episodes/fig/pValue2.png deleted file mode 100644 index 37296fc90..000000000 Binary files a/episodes/fig/pValue2.png and /dev/null differ diff --git a/episodes/statistics.Rmd b/episodes/statistics.Rmd index fa2850379..3d4582776 100644 --- a/episodes/statistics.Rmd +++ b/episodes/statistics.Rmd @@ -1,5 +1,5 @@ --- -title: "Basic Statistics" +title: "Basic Statistics: describing, modelling and reporting" teaching: 60 exercises: 20 source: Rmd @@ -21,18 +21,6 @@ source: Rmd :::::::::::::::::::::::::::::::::::::::::::::::::: -```{r, include = FALSE} -knitr::opts_chunk$set(error = TRUE) -``` - -```{r libraries, message=FALSE, warning=FALSE} -# Packages and data we'll use in this episode -library(tidyverse) -library(lubridate) -``` - -# Introduction - ## Content - Types of Data @@ -40,36 +28,23 @@ library(lubridate) - Descriptive Statistics - Inferential Statistics -## Getting the data - -In this episode, we will work with a subset of the [CCHIC](https://doi.org/10.1016/j.ijmedinf.2018.01.006) -dataset. You can load the data directly in your R session by running the following script. - -```{r, eval=FALSE, echo=TRUE} -## Create a data folder -dir.create("data", showWarnings = FALSE) # `showWarnings = FALSE` avoids warning if the folder already exists -download.file( - "https://raw.githubusercontent.com/UCL/ClinicianCoders/main/episodes/data/intermediate_CCHIC.csv", - destfile = "data/intermediate_CCHIC.csv" -) -``` - -::::::::::::::::::::::::::::::::::::: instructor - -- Help them load the dataset if needed. This is the same one they used in the morning. It should include the *length of stay* variable. -- Point out that these commands should be run only once, in the console -::::::::::::::::::::::::::::::::::::::::::::::::: +## Data -We can then load the data locally by running - -```{r load-data} -cchic <- read_csv("data/intermediate_CCHIC.csv") +```{r libraries, message=FALSE, warning=FALSE} +# We will need these libraries and this data later. +library(tidyverse) +library(lubridate) +library(gapminder) +# create a binary membership variable for europe (for later examples) +gapminder <- gapminder %>% + mutate(european = continent == "Europe") ``` +We are going to use the data from the gapminder package. We have added a variable *European* indicating if a country is in Europe. ## The big picture -- Research often seeks to answer a question about a larger population by collecting data on a small portion +- Research often seeks to answer a question about a larger population by collecting data on a small sample - Data collection: - Many variables - For each person/unit. @@ -78,72 +53,9 @@ cchic <- read_csv("data/intermediate_CCHIC.csv") ## Descriptive and inferential statistics ::: Background -Just as data in general are of different types - for example numeric vs text data - statistical data are assigned to different *levels of measure* The level of measure determines how we can describe and model the data. +Just as data in general are of different types - for example numeric vs text data - statistical data are assigned to different *levels of measure*. The level of measure determines how we can describe and model the data. ::: -# Data types - -## Continuous - -Continuous data is data that can take any value in the appropriate metric space. Examples are variables like *height* and *temperature*. Very often this is any point on the real number line. Ratio data are data that can form ratios, such that a score of seventy is twice a score of thirty five, and where the intervals between adjacent values is equal. Ratio level data also have a 'true' zero (the phenomenon measured is absent), rather than an arbitrary of calibrated zero (zero degrees Celsius is the freezing point of water.) - -There is no limit in general to the mathematical operations we can carry out on continuous data. - -::::::::::::::::::::::::::::::::::::: callout -Side Note It is worth noting that *interval* level data are often included as **continuous** since they can mostly be treated just like ratio data, aside from the calculation of the *coefficient of variation*, but by strict definition they are discrete. -::::::::::::::::::::::::::::::::::::::::::::::::: - -## Discrete - -Discrete data take their value from a closed set of possible values. There is no bound as to what the elements of the set may be - they can be integer values, fractional values, or entirely non-numeric. - -Nominal data are data whose observation entails assigning them to a category from a collection of labelled categories. An example might be eye-colour. The only mathematical procedure we can use with nominal data is *counting* so as to report *frequency* of occurrence and from these frequencies, proportions. Thus the measure of location or of central location for nominal data is **the mode** and the only measure of variability or dispersion is **the variation ratio**. - -Ordinal data are discrete data items that can be ranked. So, as well as counting items they can be **ordered**. The mode can almost always be calculated for ordinal data, but it may also be possible to calculate the **median** as an alternative measure of central location. Variability in ordinal data is indicated by **range** and **interquartile range**. - -Interval - -Interval data are numeric data that are ordered on a scale where the distance between measuring points is equal. Unlike ratio data, the zero point on an interval scale is an arbitrarily chosen calibration and data measurements do not form ratios. - -# Continuous variables - -- e.g. age, height, weight -- Have distributions: - - Gaussian - - Poisson - - Binomial - - Cauchy/Lorenz -- Can't be described - -![](./fig/ContinuousDistribution.png) - -## What is normally distributed data? - -![](./fig/NormalDistribution.png) - - -# Discrete variables - -## Types of discrete variables - -### Nominal - -- e.g. hair colour, types of antibiotics -- There is no order between the data types (e.g. blonde, brunette, red hair) - -### Ordinal - -- There is an order e.g. `care_level` where Level 3 \> Level 2 \> Level 1 etc. -- However, the difference between Level 1 and Level 2 critical care may not be the same as the difference between Level 2 and Level 3. - -![](./fig/OrdinalData.png) - -### Interval - -- There is an order to data points (e.g. `age_cat` for age centile) and the difference between these points are equal (e.g. 10 years) - -![](./fig/IntervalData.png) - # Describing data - Continuous variables @@ -153,33 +65,29 @@ Interval data are numeric data that are ordered on a scale where the distance be How do we convey information on what your data looks like, using numbers or figures? ::: -## Describing continuous data +### Describing continuous data. First establish the distribution of the data. You can visualise this with a histogram. -```{r, eval = F} -ggplot(cchic, aes(x = age_years)) + +```{r} +ggplot(gapminder, aes(x = gdpPercap)) + geom_histogram() ``` What is the distribution of this data? -![](./fig/HistogramAge.png) +### What is the distribution of population? -### What is the distribution of height? +The raw values are difficult to visualise, so we can take the log of the values and log those. Try this command -Try this command - -```{r, eval = FALSE} -ggplot(data = cchic, aes(x = height)) + +```{r include=TRUE} +ggplot(data = gapminder, aes(log(pop))) + geom_histogram() ``` What is the distribution of this data? -![](./fig/hist_height.png) - -### Parametric vs non-parametric analysis +## Parametric vs non-parametric analysis - Parametric analysis assumes that - The data follows a known distribution @@ -192,7 +100,7 @@ What is the distribution of this data? Emphasise that parametric is not equal to normal. :::::::::::::::::::::::::::::::::::::::::::::::: -#### Describing parametric and non-parametric data +### Describing parametric and non-parametric data How do you use numbers to convey what your data looks like. @@ -205,13 +113,12 @@ How do you use numbers to convey what your data looks like. - Use the median (the middle number when they are ranked from lowest to highest) and the interquartile range (the number 75% of the way up the list when ranked minus the number 25% of the way) - You can use the command `summary(data_frame_name)` to get these numbers for each variable. -#### Mean and standard deviation +## Mean versus standard deviation - What does standard deviation mean? - Both graphs have the same mean (center), but the second one has data which is more spread out. -```{r, eval = FALSE} - +```{r} # small standard deviation dummy_1 <- rnorm(1000, mean = 10, sd = 0.5) dummy_1 <- as.data.frame(dummy_1) @@ -219,7 +126,7 @@ ggplot(dummy_1, aes(x = dummy_1)) + geom_histogram() # larger standard deviation -dummy_2 <- rnorm(1000, mean = 10, sd = 20) +dummy_2 <- rnorm(1000, mean = 10, sd = 200) dummy_2 <- as.data.frame(dummy_2) ggplot(dummy_2, aes(x = dummy_2)) + geom_histogram() @@ -229,33 +136,33 @@ ggplot(dummy_2, aes(x = dummy_2)) + Get them to plot the graphs. Explain that we are generating random data from different distributions and plotting them. :::::::::::::::::::::::::::::::::::::::::::::::: -##### Calculating mean and standard deviation +### Calculating mean and standard deviation -```{r, eval = T} -mean(cchic$height, na.rm = TRUE) +```{r} +mean(gapminder$pop, na.rm = TRUE) ``` Calculate the standard deviation and confirm that it is the square root of the variance: -```{r, eval = T} -sdheight = sd(cchic$height, na.rm = TRUE) - -varheight = var(cchic$height, na.rm = TRUE) - -sqrt(varheight) == sdheight +```{r} +sdpopulation <- sd(gapminder$pop, na.rm = TRUE) +print(sdpopulation) +varpopulation <- var(gapminder$pop, na.rm = TRUE) +print(varpopulation) +sqrt(varpopulation) == sdpopulation ``` The `na.rm` argument tells R to ignore missing values in the variable. -#### Mean and interquartile range +### Calculating median and interquartile range -```{r, eval = T} -median(cchic$age_years, na.rm = TRUE) +```{r} +median(gapminder$pop, na.rm = TRUE) ``` -```{r, eval = T} -IQR(cchic$age_years, na.rm = TRUE) +```{r} +IQR(gapminder$gdpPercap, na.rm = TRUE) ``` Again, we ignore the missing values. @@ -264,21 +171,24 @@ Again, we ignore the missing values. - Frequencies -```{r, eval = T} -table(cchic$vital_status) +```{r} +table(gapminder$continent) ``` - Proportions -```{r, eval = T} -status <- table(cchic$vital_status) -prop.table(status) +```{r} +continenttable <- table(gapminder$continent) +prop.table(continenttable) ``` Contingency tables of frequencies can also be tabulated with **table()**. For example: ```{r} -table(cchic$vital_status, cchic$chemo) +table( + gapminder$country[gapminder$year == 2007], + gapminder$continent[gapminder$year == 2007] +) ``` Which leads quite naturally to the consideration of any association between the observed frequencies. @@ -299,24 +209,6 @@ Always: the level of the independent variable has no effect on the level of the - Interpreting the result -## What is a p-value? - -![](./fig/pValue.png) - -[The Lady Tasting Tea](https://analyticalsciencejournals.onlinelibrary.wiley.com/doi/10.1002/cem.3239) - -Fisher informally characterised the *p-value* as an estimate of the strength of the evidence against the null hypothesis [^1] (Dahiru T. (2008). P - value, a true test of statistical significance? A cautionary note. Annals of Ibadan postgraduate medicine, 6(1), 21--26. ) - -[^1]: Dahiru T. (2008). P - value, a true test of statistical significance? A cautionary note. *Annals of Ibadan postgraduate medicine*, *6*(1), 21--26. - -Depending on the data under consideration and our purpose, we choose a threshold of evidence for the rejection of the null hypothesis. For many purposes, a confidence level of 95% is chosen, which means that a p-value of less than 0.05 is sufficient to reject the null hypothesis. In other circumstances and confidence level of 99% may be appropriate, or even higher. - -::: callout -**What we are usually hoping for...** - -![](./fig/pValue2.png) -::: - ## Testing significance - p-value @@ -329,7 +221,7 @@ Depending on the data under consideration and our purpose, we choose a threshold **0.05** is not a magic number. -### Comparing means +## Comparing means It all starts with a hypothesis @@ -338,7 +230,7 @@ It all starts with a hypothesis - Alternate hypothesis - "There is a difference in mean height between men and women" -### More on hypothesis testing +## More on hypothesis testing - The null hypothesis (H0) assumes that the true mean difference (μd) is equal to zero. @@ -352,24 +244,20 @@ It all starts with a hypothesis ## Comparing means -Is there an absolute difference between the heights of males and females? +Is there an absolute difference between the populations of European vs non-European countries? ```{r} -cchic %>% - group_by(sex) %>% - summarise(av.height = mean(height, na.rm = TRUE)) +gapminder %>% + group_by(european) %>% + summarise(av.popn = mean(pop, na.rm = TRUE)) ``` -Is the difference between heights statistically significant? - -### t-test -- Compares means between two populations -- Paired vs. Unpaired +Is the difference between heights statistically significant? -![](./fig/Ttest.png) +## t-test -#### Assumptions of a t-test +### Assumptions of a t-test - One independent categorical variable with 2 groups and one dependent continuous variable @@ -379,150 +267,80 @@ Is the difference between heights statistically significant? - For students' original t-statistic, that the variances in both groups are more or less equal. This constraint should probably be abandoned in favour of always using a conservative test. -#### Doing a t-test - -```{r, eval = FALSE} -t.test(height ~ sex, data = cchic) -``` - -::::::::::::::::::::::::::::::::::::: instructor -Tell them to do this. The default for t.test() is that variances are unequal and it produces Welch's statistic. -:::::::::::::::::::::::::::::::::::::::::::::::: - -```{r, echo = FALSE} -t.test(height ~ sex, data = cchic) -``` - -::::::::::::::::::::::::::::::::::::: instructor -Quickly explain the main points of the output -:::::::::::::::::::::::::::::::::::::::::::::::: - -## Comparing counts - -- Is survival different between genders? +## Doing a t-test ```{r} -table(cchic$sex, cchic$vital_status) +t.test(pop ~ european, data = gapminder)$statistic +t.test(pop ~ european, data = gapminder)$parameter ``` -### What is our hypothesis? +Notice that the summary()** of the test contains more data than is output by default. + -- Null hypothesis - - There is no difference in survival between men and women -- Alternate hypothesis - - There is a difference in survival between men and women +Write a paragraph in markdown format reporting this test result including the t-statistic, the degrees of freedom, the confidence interval and the p-value to 4 places. To do this include your r code **inline** with your text, rather than in an R code chunk. -### Assumptions of the chi-squared test. +### t-test result -1. Data in cells should be frequencies or counts *not* percentages -2. Levels/Categories are mutually exclusive -- here being a alive/dead applies -3. Each subject contributes to one cell -- can either be male/female and alive/dead -4. Independent study groups -5. 2 categorical variables -6. Expected values in no more than 20% of cells are \< 5 +Testing supported the rejection of the null hypothesis that there is no difference between mean populations of European and non-European participants (**t**=`r round(t.test(pop ~european, data = gapminder)$statistic,4)`, **df**= `r round(t.test(pop ~european, data = gapminder)$parameter,4)`, +**p**= `r round( t.test(pop ~european, data = gapminder)$p.value,4)`). -`Biochem Med (Zagreb). 2013 Jun; 23(2): 143–149.` - -### Doing the chi-squared test. - -Start with `?chisq.test`. Then do the test. - -```{r} -x <- chisq.test(cchic$sex, cchic$vital_status) -summary(x) -``` - -::::::::::::::::::::::::::::::::::::: instructor -(important as it holds for results of all statistical tests) Get them to do this, then explain the output. Do the same test, assigning the result to a data object and explain how to access the contents of the data object to show, df, expected values, residuals etc. -:::::::::::::::::::::::::::::::::::::::::::::::: - -## Non-parametric versions - -Is length of stay different between genders? - -```{r, message=FALSE} -ggplot(data = cchic, aes(x = los)) + - geom_histogram() + - facet_grid(~sex) -``` - -### When do you use a non-parametric test? - -- When any of the the following are true. - - Level of measurement is nominal or ordinal - - Unequal sample sizes - - Skewed data - - Unequal variance - - Continuous data collapsed into small number of categories - -### Using the Mann-Whitney test - -`??Mann-Whitney` will show you that the command is actually called `wilcox.test`. - -```{r} -wilcox.test(los ~ sex, data = cchic) -``` - -::::::::::::::::::::::::::::::::::::: instructor -Explain the output -:::::::::::::::::::::::::::::::::::::::::::::::: +(Can you get p to display to four places? Cf *format()*.) ## More than two levels of IV -While the t-test is sufficient where there are two levels of the IV, for situations where there are more than two, we use the **ANOVA** family of procedures. To show this, we will create a variable that subsets our data by *creatinine* levels. If the ANOVA result is statistically significant, we will use a post-hoc test method to do pairwise comparisons (here Tukey's Honest Significant Differences.) +While the t-test is sufficient where there are two levels of the IV, for situations where there are more than two, we use the **ANOVA** family of procedures. To show this, we will create a variable that subsets our data by *per capita GDP* levels. If the ANOVA result is statistically significant, we will use a post-hoc test method to do pairwise comparisons (here Tukey's Honest Significant Differences.) ```{r} -quantile(cchic$creatinine) -IQR(cchic$creatinine) - -cchic$creatininegroup <- cut(cchic$creatinine, breaks = c(15, 64, 83, 123, 1533), labels = FALSE) +quantile(gapminder$gdpPercap) +IQR(gapminder$gdpPercap) -# cchic %>% -# mutate(creatininegroup = cut(cchic$creatinine, breaks=c(15, 64, 83, 123,1533), labels = FALSE)) +gapminder$gdpGroup <- cut(gapminder$gdpPercap, breaks = c(241.1659, 1202.0603, 3531.8470, 9325.4623, 113523.1329), labels = FALSE) -cchic$creatininegroup <- factor(cchic$creatininegroup) +gapminder$gdpGroup <- factor(gapminder$gdpGroup) -anovamodel <- aov(cchic$ph_abg ~ cchic$creatininegroup) +anovamodel <- aov(gapminder$pop ~ gapminder$gdpGroup) summary(anovamodel) TukeyHSD(anovamodel) ``` -## Regression Modelling +# Regression Modelling -The most common use of regression modelling is to explore the relationship between two continuous variables, for example between `temp_c` and `temp_nc` in our data. We can first determine whether there is any significant correlation between the values, and if there is, plot the relationship. +The most common use of regression modelling is to explore the relationship between two continuous variables, for example between `gdpPercap` and `lifeExp` in our data. We can first determine whether there is any significant correlation between the values, and if there is, plot the relationship. ```{r} -cor.test(cchic$temp_c, cchic$temp_nc) +cor.test(gapminder$gdpPercap, gapminder$lifeExp) -ggplot(cchic, aes(temp_c, temp_nc)) + +ggplot(gapminder, aes(gdpPercap, log(lifeExp))) + geom_point() + - geom_smooth(method = "lm") - + geom_smooth() ``` -Having decided that a further investigation of this relationship is worthwhile, we can create a linear model with the function `lm()` +Having decided that a further investigation of this relationship is worthwhile, we can create a linear model with the function `lm()`. ``` {r} -modelone <- lm(cchic$temp_nc ~ cchic$temp_c) +modelone <- lm(gapminder$gdpPercap ~ gapminder$lifeExp) summary(modelone) - ``` -### Regression with a categorical IV (the t-test) +## Regression with a categorical IV (the t-test) Run the following code chunk and compare the results to the t test conducted earlier. ```{r} -cchic %>% - mutate(sex = factor(sex)) +gapminder %>% + mutate(european = factor(european)) -modelttest <- lm(cchic$height ~ cchic$sex) +modelttest <- lm(gapminder$pop ~ gapminder$european) summary(modelttest) - ``` -### Regression with a categorical IV (ANOVA) +## Regression with a categorical IV (ANOVA) + +Use the `lm()` function to model the relationship between `gapminder$gdpGroup` +and `gapminder$pop`. Compare the results with the ANOVA carried out earlier. + +## Lunch -Use the `lm()` function to model the relationship between `cchic$creatininegroup` and `cchic$ph_abg`. Compare the results with the ANOVA carried out earlier. +- Feel free to explore the handout and go through the exercises again. diff --git a/renv/profiles/lesson-requirements/renv.lock b/renv/profiles/lesson-requirements/renv.lock index c41c4277a..a81c60368 100644 --- a/renv/profiles/lesson-requirements/renv.lock +++ b/renv/profiles/lesson-requirements/renv.lock @@ -112,7 +112,7 @@ "Package": "askpass", "Version": "1.2.0", "Source": "Repository", - "Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest", + "Repository": "CRAN", "Requirements": [ "sys" ], @@ -122,7 +122,7 @@ "Package": "backports", "Version": "1.4.1", "Source": "Repository", - "Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest", + "Repository": "CRAN", "Requirements": [ "R" ], @@ -327,7 +327,7 @@ "Package": "curl", "Version": "5.2.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "https://carpentries.r-universe.dev", "Requirements": [ "R" ], @@ -410,7 +410,7 @@ "Package": "dtplyr", "Version": "1.3.1", "Source": "Repository", - "Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -429,7 +429,7 @@ "Package": "ellipsis", "Version": "0.3.2", "Source": "Repository", - "Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest", + "Repository": "CRAN", "Requirements": [ "R", "rlang" @@ -512,6 +512,17 @@ ], "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a" }, + "gapminder": { + "Package": "gapminder", + "Version": "1.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "tibble" + ], + "Hash": "3a6fab978494586e851b8763996821d6" + }, "gargle": { "Package": "gargle", "Version": "1.5.2", @@ -585,7 +596,7 @@ "Package": "googledrive", "Version": "2.1.1", "Source": "Repository", - "Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -610,7 +621,7 @@ "Package": "googlesheets4", "Version": "1.1.1", "Source": "Repository", - "Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest", + "Repository": "CRAN", "Requirements": [ "R", "cellranger", @@ -1069,7 +1080,7 @@ "Package": "ragg", "Version": "1.3.1", "Source": "Repository", - "Repository": "carpentries", + "Repository": "https://carpentries.r-universe.dev", "Requirements": [ "systemfonts", "textshaping" @@ -1113,7 +1124,7 @@ "Package": "readxl", "Version": "1.4.3", "Source": "Repository", - "Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest", + "Repository": "CRAN", "Requirements": [ "R", "cellranger", @@ -1128,14 +1139,14 @@ "Package": "rematch", "Version": "2.0.0", "Source": "Repository", - "Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest", + "Repository": "CRAN", "Hash": "cbff1b666c6fa6d21202f07e2318d4f1" }, "rematch2": { "Package": "rematch2", "Version": "2.1.2", "Source": "Repository", - "Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest", + "Repository": "CRAN", "Requirements": [ "tibble" ], @@ -1284,7 +1295,7 @@ "Package": "stringi", "Version": "1.8.4", "Source": "Repository", - "Repository": "carpentries", + "Repository": "https://carpentries.r-universe.dev", "Requirements": [ "R", "stats", @@ -1321,7 +1332,7 @@ "Package": "systemfonts", "Version": "1.0.6", "Source": "Repository", - "Repository": "RSPM", + "Repository": "https://carpentries.r-universe.dev", "Requirements": [ "R", "cpp11"