Dataframe

Data Structures

  • vectors

  • factors

  • lists

  • matrices

  • arrays

  • dataframes

Dataframe

The dataframe is the most “complex”, useful and powerful structure in R. Intuitively it is an excel sheet, while from R’s point of view it is a type of list with some properties/restrictions

  • each element of the list is a vector with an associated name (aka a column)
  • each list/column must have the same number of elements
  • as a consequence, each row has the same number of elements (rectangular structure)

Creation

Most of the time you will import dataframes rather than create them, but it is important to first understand how they work and how to create/manipulate them. They are created with the data.frame command

# Create a dataframe with 3 columns
my_df <- data.frame( col1 = 1:4, col2 = letters[1:4],
                    col3 = rnorm(n = 4, mean = 0, sd = 1))
my_df
  col1 col2       col3
1    1    a  1.7779579
2    2    b -0.2343056
3    3    c  1.5753641
4    4    d  2.0025113

Attributes

The dataframe has both the attributes of a list, i.e. the names, and the attributes of a matrix, i.e. the dimensions (rows and columns)

attributes(my_df)
$names
[1] "col1" "col2" "col3"

$class
[1] "data.frame"

$row.names
[1] 1 2 3 4
dim(my_df)
[1] 4 3

As with the other structures we have seen, we can use the functions names() , dim(), nrow(), ncol()… to get information about the properties of the dataframe.

names(iris) # iris is a dataset available by default in R (?iris)
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"     
nrow(iris)
[1] 150
ncol(iris)
[1] 5

The most useful function is str(), since it gives us a quick overview of the structure of the dataframe: dimensions, variable types,…

str(iris) 
'data.frame':   150 obs. of  5 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

Indexing

We can use either square brackets []:

my_df
  col1 col2       col3
1    1    a  1.7779579
2    2    b -0.2343056
3    3    c  1.5753641
4    4    d  2.0025113
my_df[1]  # extract a 4x1 data.frame
  col1
1    1
2    2
3    3
4    4
my_df[[1]] # extract the first column of the data.frame
[1] 1 2 3 4
my_df[1,1] # extract the first element of the first column of the data.frame
[1] 1

…or the dollar sign $

# my_df[[1]] equivalent
my_df$col1 # extract the first column of the data.frame
[1] 1 2 3 4

… extract the first element of the first column…

my_df$col1[1] 
[1] 1

Indexing - Relational operators

One of the most common operations you will deal with is extracting/evaluating a subset of the values in your dataset:

my_df
  col1 col2       col3
1    1    a  1.7779579
2    2    b -0.2343056
3    3    c  1.5753641
4    4    d  2.0025113
# keep only the rows where the values of column1 are greater than 2
my_df[my_df$col1 > 2, ] # = my_df[my_df[1] > 2, ]
  col1 col2     col3
3    3    c 1.575364
4    4    d 2.002511

Examples

  col1 col2       col3
1    1    a  1.7779579
2    2    b -0.2343056
3    3    c  1.5753641
4    4    d  2.0025113
my_df[my_df$col1 > 2 & my_df$col1 < 4, ]
  col1 col2     col3
3    3    c 1.575364
my_df[my_df$col1== 2,  2]
[1] "b"
my_df[my_df$col1== 2,  "col2"]
[1] "b"

Indexing

There are also alternative, more compact ways of indexing. For example, using the subset() function:

subset(iris, subset = Species == "setosa" & Petal.Length > 1.7)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
25          4.8         3.4          1.9         0.2  setosa
45          5.1         3.8          1.9         0.4  setosa


equivalent to:

iris[iris$Species == "setosa" & iris$Petal.Length > 1.7,]
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
25          4.8         3.4          1.9         0.2  setosa
45          5.1         3.8          1.9         0.4  setosa

We can also select columns rather than rows with the select argument:

subset(iris, select = c(Sepal.Length, Species))
    Sepal.Length    Species
1            5.1     setosa
2            4.9     setosa
3            4.7     setosa
4            4.6     setosa
5            5.0     setosa
6            5.4     setosa
7            4.6     setosa
8            5.0     setosa
9            4.4     setosa
10           4.9     setosa
11           5.4     setosa
12           4.8     setosa
13           4.8     setosa
14           4.3     setosa
15           5.8     setosa
16           5.7     setosa
17           5.4     setosa
18           5.1     setosa
19           5.7     setosa
20           5.1     setosa
21           5.4     setosa
22           5.1     setosa
23           4.6     setosa
24           5.1     setosa
25           4.8     setosa
26           5.0     setosa
27           5.0     setosa
28           5.2     setosa
29           5.2     setosa
30           4.7     setosa
31           4.8     setosa
32           5.4     setosa
33           5.2     setosa
34           5.5     setosa
35           4.9     setosa
36           5.0     setosa
37           5.5     setosa
38           4.9     setosa
39           4.4     setosa
40           5.1     setosa
41           5.0     setosa
42           4.5     setosa
43           4.4     setosa
44           5.0     setosa
45           5.1     setosa
46           4.8     setosa
47           5.1     setosa
48           4.6     setosa
49           5.3     setosa
50           5.0     setosa
51           7.0 versicolor
52           6.4 versicolor
53           6.9 versicolor
54           5.5 versicolor
55           6.5 versicolor
56           5.7 versicolor
57           6.3 versicolor
58           4.9 versicolor
59           6.6 versicolor
60           5.2 versicolor
61           5.0 versicolor
62           5.9 versicolor
63           6.0 versicolor
64           6.1 versicolor
65           5.6 versicolor
66           6.7 versicolor
67           5.6 versicolor
68           5.8 versicolor
69           6.2 versicolor
70           5.6 versicolor
71           5.9 versicolor
72           6.1 versicolor
73           6.3 versicolor
74           6.1 versicolor
75           6.4 versicolor
76           6.6 versicolor
77           6.8 versicolor
78           6.7 versicolor
79           6.0 versicolor
80           5.7 versicolor
81           5.5 versicolor
82           5.5 versicolor
83           5.8 versicolor
84           6.0 versicolor
85           5.4 versicolor
86           6.0 versicolor
87           6.7 versicolor
88           6.3 versicolor
89           5.6 versicolor
90           5.5 versicolor
91           5.5 versicolor
92           6.1 versicolor
93           5.8 versicolor
94           5.0 versicolor
95           5.6 versicolor
96           5.7 versicolor
97           5.7 versicolor
98           6.2 versicolor
99           5.1 versicolor
100          5.7 versicolor
101          6.3  virginica
102          5.8  virginica
103          7.1  virginica
104          6.3  virginica
105          6.5  virginica
106          7.6  virginica
107          4.9  virginica
108          7.3  virginica
109          6.7  virginica
110          7.2  virginica
111          6.5  virginica
112          6.4  virginica
113          6.8  virginica
114          5.7  virginica
115          5.8  virginica
116          6.4  virginica
117          6.5  virginica
118          7.7  virginica
119          7.7  virginica
120          6.0  virginica
121          6.9  virginica
122          5.6  virginica
123          7.7  virginica
124          6.3  virginica
125          6.7  virginica
126          7.2  virginica
127          6.2  virginica
128          6.1  virginica
129          6.4  virginica
130          7.2  virginica
131          7.4  virginica
132          7.9  virginica
133          6.4  virginica
134          6.3  virginica
135          6.1  virginica
136          7.7  virginica
137          6.3  virginica
138          6.4  virginica
139          6.0  virginica
140          6.9  virginica
141          6.7  virginica
142          6.9  virginica
143          5.8  virginica
144          6.8  virginica
145          6.7  virginica
146          6.7  virginica
147          6.3  virginica
148          6.5  virginica
149          6.2  virginica
150          5.9  virginica

We can also combine the two:

subset(iris, subset = Species == "setosa" & Sepal.Length > 4, 
       select = c(Sepal.Length, Species))
   Sepal.Length Species
1           5.1  setosa
2           4.9  setosa
3           4.7  setosa
4           4.6  setosa
5           5.0  setosa
6           5.4  setosa
7           4.6  setosa
8           5.0  setosa
9           4.4  setosa
10          4.9  setosa
11          5.4  setosa
12          4.8  setosa
13          4.8  setosa
14          4.3  setosa
15          5.8  setosa
16          5.7  setosa
17          5.4  setosa
18          5.1  setosa
19          5.7  setosa
20          5.1  setosa
21          5.4  setosa
22          5.1  setosa
23          4.6  setosa
24          5.1  setosa
25          4.8  setosa
26          5.0  setosa
27          5.0  setosa
28          5.2  setosa
29          5.2  setosa
30          4.7  setosa
31          4.8  setosa
32          5.4  setosa
33          5.2  setosa
34          5.5  setosa
35          4.9  setosa
36          5.0  setosa
37          5.5  setosa
38          4.9  setosa
39          4.4  setosa
40          5.1  setosa
41          5.0  setosa
42          4.5  setosa
43          4.4  setosa
44          5.0  setosa
45          5.1  setosa
46          4.8  setosa
47          5.1  setosa
48          4.6  setosa
49          5.3  setosa
50          5.0  setosa

… equivalent to:

iris[iris$Species == "setosa" & iris$Sepal.Length > 4,
     c("Sepal.Length","Species")]

Indexing

Most of the time you will access variables with the $ operator. This command can also be used to create a new variable…

# create a variable that is the sum of Length and Width
iris$sum <- iris$Sepal.Length + iris$Sepal.Width
iris[, c("Sepal.Length", "Sepal.Width", "sum")]
    Sepal.Length Sepal.Width  sum
1            5.1         3.5  8.6
2            4.9         3.0  7.9
3            4.7         3.2  7.9
4            4.6         3.1  7.7
5            5.0         3.6  8.6
6            5.4         3.9  9.3
7            4.6         3.4  8.0
8            5.0         3.4  8.4
9            4.4         2.9  7.3
10           4.9         3.1  8.0
11           5.4         3.7  9.1
12           4.8         3.4  8.2
13           4.8         3.0  7.8
14           4.3         3.0  7.3
15           5.8         4.0  9.8
16           5.7         4.4 10.1
17           5.4         3.9  9.3
18           5.1         3.5  8.6
19           5.7         3.8  9.5
20           5.1         3.8  8.9
21           5.4         3.4  8.8
22           5.1         3.7  8.8
23           4.6         3.6  8.2
24           5.1         3.3  8.4
25           4.8         3.4  8.2
26           5.0         3.0  8.0
27           5.0         3.4  8.4
28           5.2         3.5  8.7
29           5.2         3.4  8.6
30           4.7         3.2  7.9
31           4.8         3.1  7.9
32           5.4         3.4  8.8
33           5.2         4.1  9.3
34           5.5         4.2  9.7
35           4.9         3.1  8.0
36           5.0         3.2  8.2
37           5.5         3.5  9.0
38           4.9         3.6  8.5
39           4.4         3.0  7.4
40           5.1         3.4  8.5
41           5.0         3.5  8.5
42           4.5         2.3  6.8
43           4.4         3.2  7.6
44           5.0         3.5  8.5
45           5.1         3.8  8.9
46           4.8         3.0  7.8
47           5.1         3.8  8.9
48           4.6         3.2  7.8
49           5.3         3.7  9.0
50           5.0         3.3  8.3
51           7.0         3.2 10.2
52           6.4         3.2  9.6
53           6.9         3.1 10.0
54           5.5         2.3  7.8
55           6.5         2.8  9.3
56           5.7         2.8  8.5
57           6.3         3.3  9.6
58           4.9         2.4  7.3
59           6.6         2.9  9.5
60           5.2         2.7  7.9
61           5.0         2.0  7.0
62           5.9         3.0  8.9
63           6.0         2.2  8.2
64           6.1         2.9  9.0
65           5.6         2.9  8.5
66           6.7         3.1  9.8
67           5.6         3.0  8.6
68           5.8         2.7  8.5
69           6.2         2.2  8.4
70           5.6         2.5  8.1
71           5.9         3.2  9.1
72           6.1         2.8  8.9
73           6.3         2.5  8.8
74           6.1         2.8  8.9
75           6.4         2.9  9.3
76           6.6         3.0  9.6
77           6.8         2.8  9.6
78           6.7         3.0  9.7
79           6.0         2.9  8.9
80           5.7         2.6  8.3
81           5.5         2.4  7.9
82           5.5         2.4  7.9
83           5.8         2.7  8.5
84           6.0         2.7  8.7
85           5.4         3.0  8.4
86           6.0         3.4  9.4
87           6.7         3.1  9.8
88           6.3         2.3  8.6
89           5.6         3.0  8.6
90           5.5         2.5  8.0
91           5.5         2.6  8.1
92           6.1         3.0  9.1
93           5.8         2.6  8.4
94           5.0         2.3  7.3
95           5.6         2.7  8.3
96           5.7         3.0  8.7
97           5.7         2.9  8.6
98           6.2         2.9  9.1
99           5.1         2.5  7.6
100          5.7         2.8  8.5
101          6.3         3.3  9.6
102          5.8         2.7  8.5
103          7.1         3.0 10.1
104          6.3         2.9  9.2
105          6.5         3.0  9.5
106          7.6         3.0 10.6
107          4.9         2.5  7.4
108          7.3         2.9 10.2
109          6.7         2.5  9.2
110          7.2         3.6 10.8
111          6.5         3.2  9.7
112          6.4         2.7  9.1
113          6.8         3.0  9.8
114          5.7         2.5  8.2
115          5.8         2.8  8.6
116          6.4         3.2  9.6
117          6.5         3.0  9.5
118          7.7         3.8 11.5
119          7.7         2.6 10.3
120          6.0         2.2  8.2
121          6.9         3.2 10.1
122          5.6         2.8  8.4
123          7.7         2.8 10.5
124          6.3         2.7  9.0
125          6.7         3.3 10.0
126          7.2         3.2 10.4
127          6.2         2.8  9.0
128          6.1         3.0  9.1
129          6.4         2.8  9.2
130          7.2         3.0 10.2
131          7.4         2.8 10.2
132          7.9         3.8 11.7
133          6.4         2.8  9.2
134          6.3         2.8  9.1
135          6.1         2.6  8.7
136          7.7         3.0 10.7
137          6.3         3.4  9.7
138          6.4         3.1  9.5
139          6.0         3.0  9.0
140          6.9         3.1 10.0
141          6.7         3.1  9.8
142          6.9         3.1 10.0
143          5.8         2.7  8.5
144          6.8         3.2 10.0
145          6.7         3.3 10.0
146          6.7         3.0  9.7
147          6.3         2.5  8.8
148          6.5         3.0  9.5
149          6.2         3.4  9.6
150          5.9         3.0  8.9

The same concepts we have seen for vectors apply, so you can both create and modify variables…

my_df <- data.frame(num = 1:4, let = letters[1:4])

# Modify the num variable by adding 1
my_df$num <- my_df$num+1
my_df$num
[1] 2 3 4 5
# Create a third variable ?paste
my_df$both <- paste(my_df$num, my_df$let, sep = "_") 
my_df$both
[1] "2_a" "3_b" "4_c" "5_d"

Combining Dataframes

Dataframes can be combined with the rbind() function:

# create a second dataframe
my_df2 <- data.frame(num = 4:7, lett = letters[1:4],
                    both = paste(4:7,letters[1:4], sep = "_"))

# join the two
my_df3 <- rbind(my_df,my_df2)
Error in `match.names()`:
! names do not match previous names

Rules

  • The dataframes must have the same number of columns

  • The column names must be identical

str(my_df)
'data.frame':   4 obs. of  3 variables:
 $ num : num  2 3 4 5
 $ let : chr  "a" "b" "c" "d"
 $ both: chr  "2_a" "3_b" "4_c" "5_d"
str(my_df2)
'data.frame':   4 obs. of  3 variables:
 $ num : int  4 5 6 7
 $ lett: chr  "a" "b" "c" "d"
 $ both: chr  "4_a" "5_b" "6_c" "7_d"

Fix the names

names(my_df2)
[1] "num"  "lett" "both"
names(my_df)
[1] "num"  "let"  "both"
# I want the names of my_df2 to match the names of my_df
names(my_df2) <- names(my_df)

my_df3 <- rbind(my_df,my_df2)
str(my_df3)
'data.frame':   8 obs. of  3 variables:
 $ num : num  2 3 4 5 4 5 6 7
 $ let : chr  "a" "b" "c" "d" ...
 $ both: chr  "2_a" "3_b" "4_c" "5_d" ...

You may also need to collect different types of data from the same participant, and then combine the collected information…

df_rt <- data.frame(subj = factor(rep(c("alice","bob"), each = 60)),
                   cond = factor(rep(c("easy","hard"),
                                     each = 30, times = 2)),
                      rt = c(rlnorm(n = 30, meanlog = -1, sdlog = .25),
                             rlnorm(n = 30, meanlog = -.7, sdlog =.3),
                             rlnorm(n = 30, meanlog = -1, sdlog = .25),
                             rlnorm(n = 30, meanlog = -.7, sdlog =.3)))
df_rt
     subj cond        rt
1   alice easy 0.2156427
2   alice easy 0.4541752
3   alice easy 0.2601258
4   alice easy 0.2454218
5   alice easy 0.3972711
6   alice easy 0.2506634
7   alice easy 0.4182994
8   alice easy 0.2366576
9   alice easy 0.3122877
10  alice easy 0.2564361
11  alice easy 0.3010954
12  alice easy 0.3919980
13  alice easy 0.4093353
14  alice easy 0.4616185
15  alice easy 0.2757101
16  alice easy 0.3837729
17  alice easy 0.3782880
18  alice easy 0.5207649
19  alice easy 0.3655499
20  alice easy 0.3303854
21  alice easy 0.5270231
22  alice easy 0.3610285
23  alice easy 0.3294952
24  alice easy 0.2862744
25  alice easy 0.2681966
26  alice easy 0.3774573
27  alice easy 0.2754994
28  alice easy 0.2826328
29  alice easy 0.4265639
30  alice easy 0.3868931
31  alice hard 0.5049556
32  alice hard 0.4589150
33  alice hard 0.6431748
34  alice hard 0.6737165
35  alice hard 0.5825246
36  alice hard 0.3170029
37  alice hard 0.5281961
38  alice hard 0.3571000
39  alice hard 0.7377066
40  alice hard 0.2790264
41  alice hard 0.4983369
42  alice hard 0.4877395
43  alice hard 0.7135274
44  alice hard 0.6340722
45  alice hard 0.4201751
46  alice hard 0.5366621
47  alice hard 0.2852757
48  alice hard 0.3493542
49  alice hard 0.3626398
50  alice hard 0.8009647
51  alice hard 0.2904118
52  alice hard 0.3191738
53  alice hard 0.3751973
54  alice hard 0.3208017
55  alice hard 0.3216682
56  alice hard 0.5814607
57  alice hard 0.6247609
58  alice hard 0.6025673
59  alice hard 0.4519792
60  alice hard 0.4583771
61    bob easy 0.2964873
62    bob easy 0.3553306
63    bob easy 0.6771791
64    bob easy 0.5098719
65    bob easy 0.1888453
66    bob easy 0.2463723
67    bob easy 0.3451090
68    bob easy 0.2558813
69    bob easy 0.3461535
70    bob easy 0.2255952
71    bob easy 0.4106174
72    bob easy 0.3527949
73    bob easy 0.2589677
74    bob easy 0.3533112
75    bob easy 0.3837833
76    bob easy 0.5297757
77    bob easy 0.3715902
78    bob easy 0.3815132
79    bob easy 0.3580085
80    bob easy 0.4204472
81    bob easy 0.2940872
82    bob easy 0.3734529
83    bob easy 0.5858972
84    bob easy 0.4230428
85    bob easy 0.4519307
86    bob easy 0.2945990
87    bob easy 0.5026947
88    bob easy 0.3882309
89    bob easy 0.2537241
90    bob easy 0.3135626
91    bob hard 0.4706438
92    bob hard 0.6117601
93    bob hard 0.5011475
94    bob hard 0.7702941
95    bob hard 0.4808341
96    bob hard 0.3553067
97    bob hard 0.8180435
98    bob hard 0.4600605
99    bob hard 0.4463754
100   bob hard 0.5423460
101   bob hard 0.4097755
102   bob hard 0.4674752
103   bob hard 0.5265917
104   bob hard 0.7984339
105   bob hard 0.5287674
106   bob hard 0.5074805
107   bob hard 0.5239723
108   bob hard 0.3151699
109   bob hard 0.4264798
110   bob hard 0.5699510
111   bob hard 0.3989696
112   bob hard 0.4931223
113   bob hard 0.4454257
114   bob hard 0.5794336
115   bob hard 0.3803694
116   bob hard 0.3987136
117   bob hard 0.4881496
118   bob hard 0.5254146
119   bob hard 0.6799087
120   bob hard 0.2700901

Dataframe containing the age:

df_age <- data.frame(subj = factor(c("alice","bob")), age = c(20,18))
df_age
   subj age
1 alice  20
2   bob  18
# structure of the reaction times dataframe
str(df_rt)
'data.frame':   120 obs. of  3 variables:
 $ subj: Factor w/ 2 levels "alice","bob": 1 1 1 1 1 1 1 1 1 1 ...
 $ cond: Factor w/ 2 levels "easy","hard": 1 1 1 1 1 1 1 1 1 1 ...
 $ rt  : num  0.216 0.454 0.26 0.245 0.397 ...
# structure of the age dataframe
str(df_age) 
'data.frame':   2 obs. of  2 variables:
 $ subj: Factor w/ 2 levels "alice","bob": 1 2
 $ age : num  20 18

In this case, we can use the merge() function …

df_all_1 <- merge(x = df_rt, y = df_age, by="subj")
df_all_1
     subj cond        rt age
1   alice easy 0.2156427  20
2   alice easy 0.4541752  20
3   alice easy 0.2601258  20
4   alice easy 0.2454218  20
5   alice easy 0.3972711  20
6   alice easy 0.2506634  20
7   alice easy 0.4182994  20
8   alice easy 0.2366576  20
9   alice easy 0.3122877  20
10  alice easy 0.2564361  20
11  alice easy 0.3010954  20
12  alice easy 0.3919980  20
13  alice easy 0.4093353  20
14  alice easy 0.4616185  20
15  alice easy 0.2757101  20
16  alice easy 0.3837729  20
17  alice easy 0.3782880  20
18  alice easy 0.5207649  20
19  alice easy 0.3655499  20
20  alice easy 0.3303854  20
21  alice easy 0.5270231  20
22  alice easy 0.3610285  20
23  alice easy 0.3294952  20
24  alice easy 0.2862744  20
25  alice easy 0.2681966  20
26  alice easy 0.3774573  20
27  alice easy 0.2754994  20
28  alice easy 0.2826328  20
29  alice easy 0.4265639  20
30  alice easy 0.3868931  20
31  alice hard 0.5049556  20
32  alice hard 0.4589150  20
33  alice hard 0.6431748  20
34  alice hard 0.6737165  20
35  alice hard 0.5825246  20
36  alice hard 0.3170029  20
37  alice hard 0.5281961  20
38  alice hard 0.3571000  20
39  alice hard 0.7377066  20
40  alice hard 0.2790264  20
41  alice hard 0.4983369  20
42  alice hard 0.4877395  20
43  alice hard 0.7135274  20
44  alice hard 0.6340722  20
45  alice hard 0.4201751  20
46  alice hard 0.5366621  20
47  alice hard 0.2852757  20
48  alice hard 0.3493542  20
49  alice hard 0.3626398  20
50  alice hard 0.8009647  20
51  alice hard 0.2904118  20
52  alice hard 0.3191738  20
53  alice hard 0.3751973  20
54  alice hard 0.3208017  20
55  alice hard 0.3216682  20
56  alice hard 0.5814607  20
57  alice hard 0.6247609  20
58  alice hard 0.6025673  20
59  alice hard 0.4519792  20
60  alice hard 0.4583771  20
61    bob easy 0.2964873  18
62    bob easy 0.3553306  18
63    bob easy 0.6771791  18
64    bob easy 0.5098719  18
65    bob easy 0.1888453  18
66    bob easy 0.2463723  18
67    bob easy 0.3451090  18
68    bob easy 0.2558813  18
69    bob easy 0.3461535  18
70    bob easy 0.2255952  18
71    bob easy 0.4106174  18
72    bob easy 0.3527949  18
73    bob easy 0.2589677  18
74    bob easy 0.3533112  18
75    bob easy 0.3837833  18
76    bob easy 0.5297757  18
77    bob easy 0.3715902  18
78    bob easy 0.3815132  18
79    bob easy 0.3580085  18
80    bob easy 0.4204472  18
81    bob easy 0.2940872  18
82    bob easy 0.3734529  18
83    bob easy 0.5858972  18
84    bob easy 0.4230428  18
85    bob easy 0.4519307  18
86    bob easy 0.2945990  18
87    bob easy 0.5026947  18
88    bob easy 0.3882309  18
89    bob easy 0.2537241  18
90    bob easy 0.3135626  18
91    bob hard 0.4706438  18
92    bob hard 0.6117601  18
93    bob hard 0.5011475  18
94    bob hard 0.7702941  18
95    bob hard 0.4808341  18
96    bob hard 0.3553067  18
97    bob hard 0.8180435  18
98    bob hard 0.4600605  18
99    bob hard 0.4463754  18
100   bob hard 0.5423460  18
101   bob hard 0.4097755  18
102   bob hard 0.4674752  18
103   bob hard 0.5265917  18
104   bob hard 0.7984339  18
105   bob hard 0.5287674  18
106   bob hard 0.5074805  18
107   bob hard 0.5239723  18
108   bob hard 0.3151699  18
109   bob hard 0.4264798  18
110   bob hard 0.5699510  18
111   bob hard 0.3989696  18
112   bob hard 0.4931223  18
113   bob hard 0.4454257  18
114   bob hard 0.5794336  18
115   bob hard 0.3803694  18
116   bob hard 0.3987136  18
117   bob hard 0.4881496  18
118   bob hard 0.5254146  18
119   bob hard 0.6799087  18
120   bob hard 0.2700901  18

… or the _join() function..

library(dplyr) # load the dplyr package

df_all_2 <- left_join(x = df_rt, y = df_age, by = c("subj")) 
df_all_2
     subj cond        rt age
1   alice easy 0.2156427  20
2   alice easy 0.4541752  20
3   alice easy 0.2601258  20
4   alice easy 0.2454218  20
5   alice easy 0.3972711  20
6   alice easy 0.2506634  20
7   alice easy 0.4182994  20
8   alice easy 0.2366576  20
9   alice easy 0.3122877  20
10  alice easy 0.2564361  20
11  alice easy 0.3010954  20
12  alice easy 0.3919980  20
13  alice easy 0.4093353  20
14  alice easy 0.4616185  20
15  alice easy 0.2757101  20
16  alice easy 0.3837729  20
17  alice easy 0.3782880  20
18  alice easy 0.5207649  20
19  alice easy 0.3655499  20
20  alice easy 0.3303854  20
21  alice easy 0.5270231  20
22  alice easy 0.3610285  20
23  alice easy 0.3294952  20
24  alice easy 0.2862744  20
25  alice easy 0.2681966  20
26  alice easy 0.3774573  20
27  alice easy 0.2754994  20
28  alice easy 0.2826328  20
29  alice easy 0.4265639  20
30  alice easy 0.3868931  20
31  alice hard 0.5049556  20
32  alice hard 0.4589150  20
33  alice hard 0.6431748  20
34  alice hard 0.6737165  20
35  alice hard 0.5825246  20
36  alice hard 0.3170029  20
37  alice hard 0.5281961  20
38  alice hard 0.3571000  20
39  alice hard 0.7377066  20
40  alice hard 0.2790264  20
41  alice hard 0.4983369  20
42  alice hard 0.4877395  20
43  alice hard 0.7135274  20
44  alice hard 0.6340722  20
45  alice hard 0.4201751  20
46  alice hard 0.5366621  20
47  alice hard 0.2852757  20
48  alice hard 0.3493542  20
49  alice hard 0.3626398  20
50  alice hard 0.8009647  20
51  alice hard 0.2904118  20
52  alice hard 0.3191738  20
53  alice hard 0.3751973  20
54  alice hard 0.3208017  20
55  alice hard 0.3216682  20
56  alice hard 0.5814607  20
57  alice hard 0.6247609  20
58  alice hard 0.6025673  20
59  alice hard 0.4519792  20
60  alice hard 0.4583771  20
61    bob easy 0.2964873  18
62    bob easy 0.3553306  18
63    bob easy 0.6771791  18
64    bob easy 0.5098719  18
65    bob easy 0.1888453  18
66    bob easy 0.2463723  18
67    bob easy 0.3451090  18
68    bob easy 0.2558813  18
69    bob easy 0.3461535  18
70    bob easy 0.2255952  18
71    bob easy 0.4106174  18
72    bob easy 0.3527949  18
73    bob easy 0.2589677  18
74    bob easy 0.3533112  18
75    bob easy 0.3837833  18
76    bob easy 0.5297757  18
77    bob easy 0.3715902  18
78    bob easy 0.3815132  18
79    bob easy 0.3580085  18
80    bob easy 0.4204472  18
81    bob easy 0.2940872  18
82    bob easy 0.3734529  18
83    bob easy 0.5858972  18
84    bob easy 0.4230428  18
85    bob easy 0.4519307  18
86    bob easy 0.2945990  18
87    bob easy 0.5026947  18
88    bob easy 0.3882309  18
89    bob easy 0.2537241  18
90    bob easy 0.3135626  18
91    bob hard 0.4706438  18
92    bob hard 0.6117601  18
93    bob hard 0.5011475  18
94    bob hard 0.7702941  18
95    bob hard 0.4808341  18
96    bob hard 0.3553067  18
97    bob hard 0.8180435  18
98    bob hard 0.4600605  18
99    bob hard 0.4463754  18
100   bob hard 0.5423460  18
101   bob hard 0.4097755  18
102   bob hard 0.4674752  18
103   bob hard 0.5265917  18
104   bob hard 0.7984339  18
105   bob hard 0.5287674  18
106   bob hard 0.5074805  18
107   bob hard 0.5239723  18
108   bob hard 0.3151699  18
109   bob hard 0.4264798  18
110   bob hard 0.5699510  18
111   bob hard 0.3989696  18
112   bob hard 0.4931223  18
113   bob hard 0.4454257  18
114   bob hard 0.5794336  18
115   bob hard 0.3803694  18
116   bob hard 0.3987136  18
117   bob hard 0.4881496  18
118   bob hard 0.5254146  18
119   bob hard 0.6799087  18
120   bob hard 0.2700901  18
df_rt$gender <- rep(c("F","M"), each = 60)
df_age$gender <- c("F","M")

df_all_g <- merge(x = df_rt, y = df_age, by=c("subj","gender"))
df_all_g
     subj gender cond        rt age
1   alice      F easy 0.2156427  20
2   alice      F easy 0.4541752  20
3   alice      F easy 0.2601258  20
4   alice      F easy 0.2454218  20
5   alice      F easy 0.3972711  20
6   alice      F easy 0.2506634  20
7   alice      F easy 0.4182994  20
8   alice      F easy 0.2366576  20
9   alice      F easy 0.3122877  20
10  alice      F easy 0.2564361  20
11  alice      F easy 0.3010954  20
12  alice      F easy 0.3919980  20
13  alice      F easy 0.4093353  20
14  alice      F easy 0.4616185  20
15  alice      F easy 0.2757101  20
16  alice      F easy 0.3837729  20
17  alice      F easy 0.3782880  20
18  alice      F easy 0.5207649  20
19  alice      F easy 0.3655499  20
20  alice      F easy 0.3303854  20
21  alice      F easy 0.5270231  20
22  alice      F easy 0.3610285  20
23  alice      F easy 0.3294952  20
24  alice      F easy 0.2862744  20
25  alice      F easy 0.2681966  20
26  alice      F easy 0.3774573  20
27  alice      F easy 0.2754994  20
28  alice      F easy 0.2826328  20
29  alice      F easy 0.4265639  20
30  alice      F easy 0.3868931  20
31  alice      F hard 0.5049556  20
32  alice      F hard 0.4589150  20
33  alice      F hard 0.6431748  20
34  alice      F hard 0.6737165  20
35  alice      F hard 0.5825246  20
36  alice      F hard 0.3170029  20
37  alice      F hard 0.5281961  20
38  alice      F hard 0.3571000  20
39  alice      F hard 0.7377066  20
40  alice      F hard 0.2790264  20
41  alice      F hard 0.4983369  20
42  alice      F hard 0.4877395  20
43  alice      F hard 0.7135274  20
44  alice      F hard 0.6340722  20
45  alice      F hard 0.4201751  20
46  alice      F hard 0.5366621  20
47  alice      F hard 0.2852757  20
48  alice      F hard 0.3493542  20
49  alice      F hard 0.3626398  20
50  alice      F hard 0.8009647  20
51  alice      F hard 0.2904118  20
52  alice      F hard 0.3191738  20
53  alice      F hard 0.3751973  20
54  alice      F hard 0.3208017  20
55  alice      F hard 0.3216682  20
56  alice      F hard 0.5814607  20
57  alice      F hard 0.6247609  20
58  alice      F hard 0.6025673  20
59  alice      F hard 0.4519792  20
60  alice      F hard 0.4583771  20
61    bob      M easy 0.2964873  18
62    bob      M easy 0.3553306  18
63    bob      M easy 0.6771791  18
64    bob      M easy 0.5098719  18
65    bob      M easy 0.1888453  18
66    bob      M easy 0.2463723  18
67    bob      M easy 0.3451090  18
68    bob      M easy 0.2558813  18
69    bob      M easy 0.3461535  18
70    bob      M easy 0.2255952  18
71    bob      M easy 0.4106174  18
72    bob      M easy 0.3527949  18
73    bob      M easy 0.2589677  18
74    bob      M easy 0.3533112  18
75    bob      M easy 0.3837833  18
76    bob      M easy 0.5297757  18
77    bob      M easy 0.3715902  18
78    bob      M easy 0.3815132  18
79    bob      M easy 0.3580085  18
80    bob      M easy 0.4204472  18
81    bob      M easy 0.2940872  18
82    bob      M easy 0.3734529  18
83    bob      M easy 0.5858972  18
84    bob      M easy 0.4230428  18
85    bob      M easy 0.4519307  18
86    bob      M easy 0.2945990  18
87    bob      M easy 0.5026947  18
88    bob      M easy 0.3882309  18
89    bob      M easy 0.2537241  18
90    bob      M easy 0.3135626  18
91    bob      M hard 0.4706438  18
92    bob      M hard 0.6117601  18
93    bob      M hard 0.5011475  18
94    bob      M hard 0.7702941  18
95    bob      M hard 0.4808341  18
96    bob      M hard 0.3553067  18
97    bob      M hard 0.8180435  18
98    bob      M hard 0.4600605  18
99    bob      M hard 0.4463754  18
100   bob      M hard 0.5423460  18
101   bob      M hard 0.4097755  18
102   bob      M hard 0.4674752  18
103   bob      M hard 0.5265917  18
104   bob      M hard 0.7984339  18
105   bob      M hard 0.5287674  18
106   bob      M hard 0.5074805  18
107   bob      M hard 0.5239723  18
108   bob      M hard 0.3151699  18
109   bob      M hard 0.4264798  18
110   bob      M hard 0.5699510  18
111   bob      M hard 0.3989696  18
112   bob      M hard 0.4931223  18
113   bob      M hard 0.4454257  18
114   bob      M hard 0.5794336  18
115   bob      M hard 0.3803694  18
116   bob      M hard 0.3987136  18
117   bob      M hard 0.4881496  18
118   bob      M hard 0.5254146  18
119   bob      M hard 0.6799087  18
120   bob      M hard 0.2700901  18

Contingency tables

We can use the table() function both to compute frequencies…

# keep only rts between .250 and 1.5 seconds
# i.e. the rows that meet this condition
df_rt_clean <- df_rt[df_rt$rt > .25 & df_rt$rt < 1.5, ]
table(df_rt_clean$subj) # trials for each subject

alice   bob 
   57    57 
table(df_rt_clean$subj, df_rt_clean$cond) # subject x condition
       
        easy hard
  alice   27   30
  bob     27   30

Exporting and importing data

In R we can import data in many different formats; most commonly you will import .csv or .xlsx data.

Here, for example, I export the dataframes in two different formats…

library(readr) # load the readr package
library(writexl) # load the writexl package

write.csv(df_rt, file = "DATA/df_rt.csv",row.names = FALSE)
write_xlsx(df_age, path = "DATA/df_age.xlsx")

Importing

library(readxl) # load the readxl package

df_rt_impo <- read_csv("DATA/df_rt.csv") # uses the readr package

df_age_impo <- read_xlsx("DATA/df_age.xlsx")

Checking the structure

str(df_rt) # Data frame we created
'data.frame':   120 obs. of  4 variables:
 $ subj  : Factor w/ 2 levels "alice","bob": 1 1 1 1 1 1 1 1 1 1 ...
 $ cond  : Factor w/ 2 levels "easy","hard": 1 1 1 1 1 1 1 1 1 1 ...
 $ rt    : num  0.216 0.454 0.26 0.245 0.397 ...
 $ gender: chr  "F" "F" "F" "F" ...
str(df_rt_impo) # Data frame we loaded
spc_tbl_ [120 × 4] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ subj  : chr [1:120] "alice" "alice" "alice" "alice" ...
 $ cond  : chr [1:120] "easy" "easy" "easy" "easy" ...
 $ rt    : num [1:120] 0.216 0.454 0.26 0.245 0.397 ...
 $ gender: chr [1:120] "F" "F" "F" "F" ...
 - attr(*, "spec")=
  .. cols(
  ..   subj = col_character(),
  ..   cond = col_character(),
  ..   rt = col_double(),
  ..   gender = col_character()
  .. )
 - attr(*, "problems")=<externalptr> 

The dataframe is imported as a tibble, and in this case the factor variables have been imported as character. This can be changed either when importing ( ?read_csv ):

df_rt_impo1 <- read_csv("DATA/df_rt.csv",
                       col_types =
                         list(col_factor(),col_factor(),
                              col_double()))
str(df_rt_impo1)
spc_tbl_ [120 × 4] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ subj  : Factor w/ 2 levels "alice","bob": 1 1 1 1 1 1 1 1 1 1 ...
 $ cond  : Factor w/ 2 levels "easy","hard": 1 1 1 1 1 1 1 1 1 1 ...
 $ rt    : num [1:120] 0.216 0.454 0.26 0.245 0.397 ...
 $ gender: chr [1:120] "F" "F" "F" "F" ...
 - attr(*, "spec")=
  .. cols(
  ..   subj = col_factor(levels = NULL, ordered = FALSE, include_na = FALSE),
  ..   cond = col_factor(levels = NULL, ordered = FALSE, include_na = FALSE),
  ..   rt = col_double(),
  ..   gender = col_character()
  .. )
 - attr(*, "problems")=<externalptr> 

or afterwards with the as.factor() command:

df_rt_impo$subj <- as.factor(df_rt_impo$subj)
df_rt_impo$cond <- as.factor(df_rt_impo$cond)
str(df_rt_impo)
spc_tbl_ [120 × 4] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ subj  : Factor w/ 2 levels "alice","bob": 1 1 1 1 1 1 1 1 1 1 ...
 $ cond  : Factor w/ 2 levels "easy","hard": 1 1 1 1 1 1 1 1 1 1 ...
 $ rt    : num [1:120] 0.216 0.454 0.26 0.245 0.397 ...
 $ gender: chr [1:120] "F" "F" "F" "F" ...
 - attr(*, "spec")=
  .. cols(
  ..   subj = col_character(),
  ..   cond = col_character(),
  ..   rt = col_double(),
  ..   gender = col_character()
  .. )
 - attr(*, "problems")=<externalptr> 

equivalent to:

df_rt_impo2 <- read_csv("DATA/df_rt.csv") %>% #library(tidyverse)
  mutate(subj = factor(subj),
         cond = factor(cond))
str(df_rt_impo2)
tibble [120 × 4] (S3: tbl_df/tbl/data.frame)
 $ subj  : Factor w/ 2 levels "alice","bob": 1 1 1 1 1 1 1 1 1 1 ...
 $ cond  : Factor w/ 2 levels "easy","hard": 1 1 1 1 1 1 1 1 1 1 ...
 $ rt    : num [1:120] 0.216 0.454 0.26 0.245 0.397 ...
 $ gender: chr [1:120] "F" "F" "F" "F" ...

(just to show you that in R a problem can be solved in different ways)

The examples I have shown concern data in formats external to R, but we can also save and import data in R formats.

Their main drawback is that they can be read (mainly) only within the R environment.

If we need to work with different software or languages, it is probably better to use a more generic format (e.g, .csv or .txt).

Now let’s practice!


Open this link and keep it open:

https://etherpad.wikimedia.org/p/arca-corsoR