2022-05-21
Recall that you set the working directory to this folder by selecting from the top menu Session>Set Working Directory>Choose Directory. Then select the folder where you are keeping all your datasets for this class. By doing this, we can load the files in this directory without having to refer to the full path for their location, and anything we save will be written to this folder.
Once you set your working directory for where you will access your stored data
Notice that the Environment now contains two objects, of the type tbl_df.
Each time you start R, it’s a good idea to click on Update in the Packages panel to update all your installed packages to the latest versions. Installing a package makes it available to you, but to use it in any R session you need to load it. You can do this by checking its box in the Packages tab. However, we will enter the following code into our script, then highlight these lines of code and run them:
Recall that the pfizer dataset contains information about Pfizer payments to doctors and warning letters sent by food and drug administration
We can View data at any time by clicking on its table icon in the Environment tab in the Grid view.
Alternatively, you can use code we learned in the last unit - head(data). Notice the variable names and types.
# A tibble: 6 × 10
org_indiv first_plus first_name last_name city state category cash other
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
1 3-D MEDICAL … STEVEN BR… STEVEN DEITELZW… NEW … LA Profess… 2625 0
2 AA DOCTORS, … AAKASH MO… AAKASH AHUJA PASO… CA Expert-… 1000 0
3 ABBO, LILIAN… LILIAN MA… LILIAN ABBO MIAMI FL Busines… 0 448
4 ABBO, LILIAN… LILIAN MA… LILIAN ABBO MIAMI FL Meals 0 119
5 ABBO, LILIAN… LILIAN MA… LILIAN ABBO MIAMI FL Profess… 1800 0
6 ABDULLAH RAF… ABDULLAH ABDULLAH RAFFEE FLINT MI Expert-… 750 0
# ℹ 1 more variable: total <dbl>
# A tibble: 6 × 5
name_last name_first name_middle issued office
<chr> <chr> <chr> <chr> <chr>
1 ADELGLASS JEFFREY M. 5/25/1999 Center for Drug Evaluation and Re…
2 ADKINSON N. FRANKLIN 4/19/2000 Center for Biologics Evaluation a…
3 ALLEN MARK S. 1/28/2002 Center for Devices and Radiologic…
4 AMSTERDAM DANIEL <NA> 11/17/2004 Center for Biologics Evaluation a…
5 AMSTUTZ HARLAN C. 7/19/2004 Center for Devices and Radiologic…
6 ANDERSON C. JOSEPH 2/25/2000 Center for Devices and Radiologic…
Notice that issued has been recognized as a Date variable. Other common data types include num, for numbers that may contain decimals and POSIXct for full date and time.
To specify an individual column use the name of the data frame and the column name, separated by $. Determine the class for the variable “total”
If you need to change the data type for any column, use the following functions:
. as.character converts to a text string
. as.numeric converts to a number
. as.factor converts to a categorical variable
. as.integer converts to an integer
. as.Date converts to a date
. as.POSIXct convets to a full date and time
(Conversions to full dates and times can get complicated, because of timezones.
The summary function will run a quick statistical summary of a data frame, calculating mean, median and quartile values for continuous variables:
org_indiv first_plus first_name last_name
Length:10087 Length:10087 Length:10087 Length:10087
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
city state category cash
Length:10087 Length:10087 Length:10087 Min. : 0
Class :character Class :character Class :character 1st Qu.: 0
Mode :character Mode :character Mode :character Median : 0
Mean : 3241
3rd Qu.: 2000
Max. :1185466
NA's :1
other total
Min. : 0.0 Min. : 0
1st Qu.: 0.0 1st Qu.: 191
Median : 41.0 Median : 750
Mean : 266.5 Mean : 3507
3rd Qu.: 262.0 3rd Qu.: 2000
Max. :27681.0 Max. :1185466
NA's :3
Now we will use dplyr to manipulate the data, using operations and functions:
. Sort: Largest to smallest, oldest to newest, alphabetical etc.
. select - Choose which columns to include.
. filter - Filter the data.
. arrange - Sort the data, by size for continuous variables, by date, or alphabetically.
. group_by - Group the data by a categorical variable.
. mutate - Create new column(s) in the data, or change existing column(s).
. rename - Rename column(s).
. bind_rows - Merge two data frames into one, combining data from columns with the same name.
. summarize - Summarize, or aggregate (for each group if following group_by). Often used in conjunction with functions including:
mean Calculate the mean, or average
median Calculate the median
max Find the maximum value
min Find the minimum value
sum Add all the values together
n Count the number of records
There are also various functions to join data, which we will explore below.
We will explore this dataset, filtering in many ways, in order to see if there are doctors who have behaved unethically by taking money from Pfizer Pharma and then we will join that dataset with the FDA dataset that reveals doctors who have received warnings for this unethical behavior.
Filter and sort the data in specific ways. For each of the following examples, copy the code that follows into your script, and view the results. Notice how we create a new objects to hold the processed data.
Find doctors in California paid $10,000 or more by Pfizer to run “Expert-Led Forums.”
Notice the use of == to find values that match the specified text, >= for greater than or equal to, and the Boolean operator &.
If you arrange without the desc function, the sort will be from smallest to largest.
Notice the use of the | Boolean operator, and the brackets around that part of the query. This ensures that this part of the query is run first. See what happens if you exclude them.
Notice the use of head, which grabs a defined number of rows from the start of a data frame. Here, it is crucial to run the sort first! See what happens if you change the order of the last two lines.
expert_advice <- pfizer %>%
filter(category == "Expert-Led Forums" | category == "Professional Advising") %>%
arrange(last_name, first_name) %>%
head(20)
expert_advice
# A tibble: 20 × 10
org_indiv first_plus first_name last_name city state category cash other
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
1 ABBO, LILIA… LILIAN MA… LILIAN ABBO MIAMI FL Profess… 1800 0
2 ABEBE, SHEI… SHEILA Y SHEILA ABEBE INDI… IN Expert-… 825 0
3 NEW YORK UN… JUDITH ANN JUDITH ABERG NEW … NY Profess… 1750 0
4 ABOLNIK, IG… IGOR Z IGOR ABOLNIK PROVO UT Expert-… 1750 0
5 ABRAKSIA, S… SAMIR SAMIR ABRAKSIA BEAC… OH Expert-… 2000 0
6 ABRAKSIA, S… SAMIR SAMIR ABRAKSIA BEAC… OH Profess… 2500 0
7 ABRAMSON, S… STEVEN BA… STEVEN ABRAMSON NEW … NY Profess… 4400 0
8 ABUZZAHAB, … FARUK S FARUK ABUZZAHAB MINN… MN Profess… 1750 0
9 ABUZZAHAB, … MARY JENN… MARY ABUZZAHAB SAIN… MN Expert-… 1000 0
10 ACCACHA, SI… SIHAM DON… SIHAM ACCACHA MINE… NY Expert-… 1250 0
11 ACEVEDO MAR… IRIS ARLE… IRIS ACEVEDO … CAGU… PR Expert-… 750 0
12 ACKERMAN, I… IVAN FOST… IVAN ACKERMAN BRAN… FL Expert-… 1250 0
13 PAIN MEDICI… WILLIAM E… WILLIAM ACKERMAN LITT… AR Expert-… 1000 0
14 ACOSTA, LUI… LUIS SILV… LUIS ACOSTA HOUS… TX Expert-… 1000 0
15 ADAMS, SAND… SANDRA GA… SANDRA ADAMS SAN … TX Profess… 12840 0
16 ADDONA, TOM… TOMMASO TOMMASO ADDONA NEW … NY Expert-… 750 0
17 HEALTH RESE… ALEX ASIE… ALEX ADJEI BUFF… NY Profess… 2000 0
18 ADLER, DAVI… DAVID ELL… DAVID ADLER PORT… OR Profess… 71 0
19 ADLER, JERE… JEREMY A JEREMY ADLER ENCI… CA Expert-… 850 0
20 ADMANI, ARI… ARIFF ARIFF ADMANI PARA… NJ Expert-… 2000 0
# ℹ 1 more variable: total <dbl>
Notice that you can sort by multiple variables, separated by commas. Use pattern matching to filter text.
This code differs only by the ! Boolean operator. Notice that it has split the data into two, based on categories of payment.
Append one data frame to another.
readr can write data to CSV and other text files.
na=“” ensures that any empty cells in the data frame are saved as blanks - R represents null values as NA, so if you don’t include this, any null values will appear as NA in the saved file.
Calculate the total payments, by state
Notice the use of group_by followed by summarize to group and summarize data, here using the function sum.
Notice the use of multiple summary functions, sum, median, and n. (You don’t specify a variable for n because it is simply counting the number of rows in the data.)
As for arrange, you can group_by by multiple variables, separated by commas.
Now let’s see how to work with dates, using the FDA warning letters data.
Filter the data for letters sent from the start of 2005 onwards. FDA sent warning letters from the start of 2005 onwards
You will have to fix “issued”” to be read as a date. If you look back at str(fda), it was read in as a chr (character). To coerce it to be a date, use the command,
Notice that operators like >= can be used for dates, as well as for numbers.
This code introduces dplyr’s mutate function to create a new column in the data. The new variable year is the four-digit year “%Y (see here for more on time and date formats in R), extracted from the issued dates using the format function. Then the code groups by year and counts the number of letters for each one.
Add columns giving the number of days and weeks that have elapsed since each letter was sent
Notice in the first line that this code changes the fda data frame, rather than creating a new object. The function Sys.Date returns the current date, and if you subtract another date, it will calculate the difference in days. To calculate date and time differences using other units, use the difftime function.
Notice also that you can mutate multiple columns at one go, separated by commas.
Here is an animation for the different types of joins: https://github.com/gadenbuie/tidyexplain
There are a number of join functions in dplyr to combine data from two data frames. Here are the most useful:
. inner_join() returns values from both tables only where there is a match
. left_join() returns all the values from the first-mentioned table, plus those from the second table that match
. semi_join() filters the first-mentioned table to include only values that have matches in the second table
. anti_join() filters the first-mentioned table to include only values that have no matches in the second table.
To illustrate, these joins will find doctors paid by Pfizer to run expert led forums who had also received a warning letter from the FDA:
The code in by=c() defines how the join should be made. If instructions on how to join the tables are not supplied, dplyr will look for columns with matching names, and perform the join based on those.
The difference between the two joins above is that the first contains all of the columns from both data frames, while the second gives only columns from the pfizer data frame.
In practice, you may wish to inner_join and then use dplyr’s select function to select the columns that you want to retain, for example:
expert_warned <- inner_join(pfizer, fda, by=c("first_name" = "name_first", "last_name" = "name_last")) %>%
filter(category=="Expert-Led Forums") %>%
select(first_plus, last_name, city, state, total, issued)
expert_warned <- inner_join(pfizer, fda, by=c("first_name" = "name_first", "last_name" = "name_last")) %>%
filter(category=="Expert-Led Forums") %>%
select(2:5,10,12)
Notice that you can select by columns’ names, or by their positions, where 1 is the first column, 3 is the third, and so on.
Comment your code
Anything that appears on a line after # will be treated as a comment, and will be ignored when the code is run. Get into the habit of commenting your code: Don’t trust yourself to remember what it does! Data journalism should ideally be fully documented and reproducible.