Skip to contents

Import data files that were created by oTree. All files containing the pattern YYYY-MM-DD at the end of their file names are considered oTree files. Bot outputs are saved by oTree without the date included. Hence, to import bot data, you must either rename the original bot files using the YYYY-MM-DD format or use the argument onlybots = TRUE. By using the second option, only data of bot files are imported.

Caution! Data can be downloaded from within the session and globally at the same time. If both files are downloaded, this can lead to the $all_apps_wide data being there twice! You can remove duplicate data by using delete_duplicate.

Caution! When importing Excel files, this function does not check for erroneous data structures and will combine all data frames with the same file name patterns. Before using the CSV = FALSE argument, clean up your data appropriately.

Usage

import_otree(
  path = ".",
  file_names = NULL,
  final_apps = NULL,
  final_pages = NULL,
  recursive = TRUE,
  csv = TRUE,
  onlybots = FALSE,
  del_empty = TRUE,
  info = FALSE,
  encoding = "UTF-8"
)

Arguments

path

Character. The path to the files (default is the working directory).

file_names

Character. The name(s) of the file(s) to be imported. If not specified, all files in the path and subfolders are imported.

final_apps

Character. The name(s) of the app(s) at which the participants have to finish the experiment. If the argument final_apps is left empty, you can still call for deleting the participants who did not finish the experiment with delete_dropouts.

final_pages

Character. The name(s) of the page(s) at which the participants have to finish the experiment. If the argument final_pages is left empty, you can still call for deleting the participants who did not finish the experiment with delete_dropouts.

recursive

Logical. TRUE if the files in the path's subfolders should also be imported.

csv

Logical. TRUE if only CSV files should be imported. FALSE if only Excel files should be imported.

onlybots

Logical. TRUE if only bot-created files should be imported.

del_empty

Logical. TRUE if all empty cases should be deleted from the $all_apps_wide or normal app data frames (not Time or Chats).

info

Logical. TRUE if a brief information on the data import should be printed.

encoding

Character. Encoding of the CSV files that are imported. Default is "UTF-8".

Value

Returns a list of data frames (one data frame for each app and $all_apps_wide) and a list of information on this list of data frames in $info.

See detailed information on the imported files in $info$imported_files.

If $all_apps_wide is imported, see the number of imported cases in $info$initial_n. In this number, empty rows are already considered. So, if empty rows are deleted with del_empty=TRUE, initial_n

counts all rows that are not empty. Cases that are deleted because the participants did not make it to the last page and/or app are not subtracted from this number.

Information: Empty rows are rows without the participant._current_app_name

variable set. Empty rows are deleted from all app data frames and $all_apps_wide when using del_empty = TRUE. Empty rows in the $Chats and $Time data frames are not deleted.

If old and new oTree versions are combined, the $Time data frame contains variables called participant_code

and participant__code (the difference is in the underscores). Caution! If there is an unusual amount of NAs, check if everything got imported correctly. Sometimes, the CSV or Excel file may be corrupted, and all information is only found in one column.

Examples

# Set data folder first
withr::with_dir(system.file("extdata", package = "gmoTree"), {

# Import all oTree files in this folder and its subfolders
oTree <- import_otree()

# Show the structure of the import
str(oTree, max.level = 1)

# Show the names of all imported files
oTree$info$imported_files

# Delete empty cases and delete every case of a person
# who didn't end the experiment in the app "survey"
oTree <- import_otree(
  del_empty = TRUE,
  final_apps = "survey",
  info = TRUE)

# Show the structure of the import
str(oTree, max.level = 1)

# Import bot files
import_otree(
  path = "./bot_data",
  onlybots = TRUE,
  csv = TRUE,
  info = TRUE)

# Show the structure of the import
str(oTree, max.level = 1)

# Import with file names (path separately)
oTree2 <- import_otree(
     del_empty = TRUE,
     path = "./exp_data",
     file_names = c("all_apps_wide-2023-03-27.csv",
                   "ChatMessages-2023-03-27.csv",
                   "PageTimes-2023-03-27.csv"),
     onlybots = FALSE,
     csv = TRUE,
     info = TRUE)

# Show the structure of the import
str(oTree, max.level = 1)

# Import with file names (without path separately)
oTree2 <- import_otree(
     del_empty = TRUE,
     file_names = c("exp_data/all_apps_wide-2023-03-27.csv",
                   "exp_data/ChatMessages-2023-03-27.csv",
                   "exp_data/PageTimes-2023-03-27.csv"),
     onlybots = FALSE,
     csv = TRUE,
     info = TRUE)

# Show the structure of the import
str(oTree, max.level = 1)
})
#> Warning: You have stored all_apps_wide globally but also room-specific. This function will import both of them. (Globally, the files are saved as "all_apps_wide_." Room-specific, the files are saved as "All apps - wide-" or "all_apps_wide-.") After importing the data, make sure nothing is there twice! (Advice: You may use delete_duplicate() to remove duplicate rows of all oTree data frames.
#> List of 10
#>  $ all_apps_wide:'data.frame':	104 obs. of  68 variables:
#>  $ info         :List of 2
#>  $ chatapp      :'data.frame':	88 obs. of  28 variables:
#>  $ dictator     :'data.frame':	213 obs. of  30 variables:
#>  $ survey       :'data.frame':	88 obs. of  33 variables:
#>  $ start        :'data.frame':	38 obs. of  28 variables:
#>  $ 2chatapp     :'data.frame':	8 obs. of  24 variables:
#>  $ dictator2    :'data.frame':	24 obs. of  25 variables:
#>  $ Time         :'data.frame':	878 obs. of  18 variables:
#>  $ Chats        :'data.frame':	95 obs. of  11 variables:
#> Warning: You have stored all_apps_wide globally but also room-specific. This function will import both of them. (Globally, the files are saved as "all_apps_wide_." Room-specific, the files are saved as "All apps - wide-" or "all_apps_wide-.") After importing the data, make sure nothing is there twice! (Advice: You may use delete_duplicate() to remove duplicate rows of all oTree data frames.
#> Imported: 7 app(s) and/or all_apps_wide
#> Imported: Time file(s)
#> Imported: Chat file(s)
#> 26 case(s) deleted
#> Dropouts are deleted from all data frames. Except: The list of oTree data frames includes a chat. As the interpretation of chat data depends on how participants engage with each other, the data must be deleted with more care than deleting data in other apps. Hence, this function does not delete data in this data frame. Please do this manually if necessary!
#> 
#> Errors when importing these files:
#> File: ./exp_wrong_data/dictator_2023-03-27.csv: Error in read.table(file = file, header = header, sep = sep, quote = quote, : more columns than column names
#> List of 10
#>  $ all_apps_wide:'data.frame':	62 obs. of  68 variables:
#>  $ info         :List of 3
#>  $ chatapp      :'data.frame':	50 obs. of  28 variables:
#>  $ dictator     :'data.frame':	111 obs. of  30 variables:
#>  $ survey       :'data.frame':	50 obs. of  33 variables:
#>  $ start        :'data.frame':	16 obs. of  28 variables:
#>  $ 2chatapp     :'data.frame':	4 obs. of  24 variables:
#>  $ dictator2    :'data.frame':	12 obs. of  25 variables:
#>  $ Time         :'data.frame':	772 obs. of  18 variables:
#>  $ Chats        :'data.frame':	95 obs. of  11 variables:
#> Imported: 4 app(s) and/or all_apps_wide
#> No Time files available
#> No chat files available
#> List of 10
#>  $ all_apps_wide:'data.frame':	62 obs. of  68 variables:
#>  $ info         :List of 3
#>  $ chatapp      :'data.frame':	50 obs. of  28 variables:
#>  $ dictator     :'data.frame':	111 obs. of  30 variables:
#>  $ survey       :'data.frame':	50 obs. of  33 variables:
#>  $ start        :'data.frame':	16 obs. of  28 variables:
#>  $ 2chatapp     :'data.frame':	4 obs. of  24 variables:
#>  $ dictator2    :'data.frame':	12 obs. of  25 variables:
#>  $ Time         :'data.frame':	772 obs. of  18 variables:
#>  $ Chats        :'data.frame':	95 obs. of  11 variables:
#> Imported: 1 app(s) and/or all_apps_wide
#> Imported: Time file(s)
#> Imported: Chat file(s)
#> List of 10
#>  $ all_apps_wide:'data.frame':	62 obs. of  68 variables:
#>  $ info         :List of 3
#>  $ chatapp      :'data.frame':	50 obs. of  28 variables:
#>  $ dictator     :'data.frame':	111 obs. of  30 variables:
#>  $ survey       :'data.frame':	50 obs. of  33 variables:
#>  $ start        :'data.frame':	16 obs. of  28 variables:
#>  $ 2chatapp     :'data.frame':	4 obs. of  24 variables:
#>  $ dictator2    :'data.frame':	12 obs. of  25 variables:
#>  $ Time         :'data.frame':	772 obs. of  18 variables:
#>  $ Chats        :'data.frame':	95 obs. of  11 variables:
#> Imported: 1 app(s) and/or all_apps_wide
#> Imported: Time file(s)
#> Imported: Chat file(s)
#> List of 10
#>  $ all_apps_wide:'data.frame':	62 obs. of  68 variables:
#>  $ info         :List of 3
#>  $ chatapp      :'data.frame':	50 obs. of  28 variables:
#>  $ dictator     :'data.frame':	111 obs. of  30 variables:
#>  $ survey       :'data.frame':	50 obs. of  33 variables:
#>  $ start        :'data.frame':	16 obs. of  28 variables:
#>  $ 2chatapp     :'data.frame':	4 obs. of  24 variables:
#>  $ dictator2    :'data.frame':	12 obs. of  25 variables:
#>  $ Time         :'data.frame':	772 obs. of  18 variables:
#>  $ Chats        :'data.frame':	95 obs. of  11 variables: