Skip to content

Commit e3a40c2

Browse files
committed
repair bug that reads a character in a numeric excel field (a version number like "9.3") and coinverts it into a character with too many significant digits
1 parent b7a091d commit e3a40c2

File tree

5 files changed

+71
-46
lines changed

5 files changed

+71
-46
lines changed

R/read.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ read_keyvalue <- function(
8080
drfile,
8181
sheet = sheet,
8282
range = range,
83-
col_names = c("key", "value")
83+
col_names = c("key", "value"),
84+
col_types = c("text", "list") # Key column is read as text; value column is read as "list" to preserve native Excel types (numeric, text, etc.), so that R's own as.character() is used for conversion instead of readxl's internal conversion which yields "9.3000000000000007" for 9.3
8485
)
8586
}) |>
8687
dplyr::bind_rows()
@@ -279,7 +280,7 @@ short_to_longnames <- gentranslator('short-long')
279280
#' Read all data from a spreadsheet according to a reporting template guide. The
280281
#' data will be returned as a list with the optional elements keyvalue, table and
281282
#' platedata if defined in the guide. The minimal and maximal template versions
282-
#' of the guide mustbe compatible with that of the template in which the data
283+
#' of the guide must be compatible with that of the template in which the data
283284
#' were recorded. Furthermore, the name of the template must match the template
284285
#' name in the guide when when `checkname` is `TRUE`.
285286
#' @details

man/read_data.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-guide.R

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
test_that("Reading a spreadsheet map works", {
2-
expect_no_error(read_guide(test_path("testdata/guide_competition_1_0.yml")))
2+
expect_no_error(read_guide(test_path("fixtures/guide_competition_1_0.yml")))
33
})
44

55
test_that("Function check_dim works", {
@@ -12,8 +12,8 @@ test_that("Function check_dim works", {
1212
})
1313

1414
#test_that("check_guide works for correct guides", {
15-
# expect_no_error(read_guide(test_path("testdata/goodguides/guide_competition_9_3.yml")))
16-
# expect_no_error(read_guide(test_path("testdata/goodguides/guide_without_platedata.yml")))
17-
# expect_no_error(read_guide(test_path("testdata/goodguides/guide_with_two_plates.yml")))
18-
# expect_no_error(read_guide(test_path("testdata/goodguides/guide_without_templatemetadata.yml")))
15+
# expect_no_error(read_guide(test_path("fixtures/goodguides/guide_competition_9_3.yml")))
16+
# expect_no_error(read_guide(test_path("fixtures/goodguides/guide_without_platedata.yml")))
17+
# expect_no_error(read_guide(test_path("fixtures/goodguides/guide_with_two_plates.yml")))
18+
# expect_no_error(read_guide(test_path("fixtures/goodguides/guide_without_templatemetadata.yml")))
1919
#})

tests/testthat/test-read.R

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
test_that("Translation from long to short names works", {
3-
guide <- read_guide(test_path("testdata/guide_competition_1_0.yml"))
3+
guide <- read_guide(test_path("fixtures/guide_competition_1_0.yml"))
44
expect_equal(long_to_shortnames("Version", guide$translations), "template.version")
55
})
66

@@ -10,7 +10,7 @@ test_that("Function long_to_short yields correct result for missing translations
1010
})
1111

1212
test_that("Function short_to_longnames works", {
13-
guide <- read_guide(test_path("testdata/guide_competition_1_0.yml"))
13+
guide <- read_guide(test_path("fixtures/guide_competition_1_0.yml"))
1414
expect_equal(short_to_longnames("template.version", guide$translations), "Version")
1515
})
1616

@@ -20,66 +20,87 @@ test_that("Function short_to_long yields correct result for missing translations
2020
})
2121

2222
test_that("reading a single key-value pair works", {
23-
expect_no_error(read_keyvalue(drfile = test_path('testdata/test1.xlsx'), sheet = 'description', range = "A2:B2"))
23+
expect_no_error(read_keyvalue(drfile = test_path('fixtures/test1.xlsx'), sheet = 'description', range = "A2:B2"))
2424
expected_result <- list('template.version' = '9.3')
25-
guide <- read_guide(test_path("testdata/guide_competition_1_0.yml"))
26-
expect_equal(read_keyvalue(drfile = test_path('testdata/test1.xlsx'), sheet = 'description', range = "A2:B2", translate = TRUE,
25+
guide <- read_guide(test_path("fixtures/guide_competition_1_0.yml"))
26+
expect_equal(read_keyvalue(drfile = test_path('fixtures/test1.xlsx'), sheet = 'description', range = "A2:B2", translate = TRUE,
2727
translations = guide$translations), expected_result)
2828
})
2929

3030
test_that("reading and coercing key-value pairs works", {
3131
expected_result_single <- list('max.spread' = 0.2)
32-
guide <- read_guide(test_path("testdata/guide_competition_1_0.yml"))
33-
expect_equal(read_keyvalue(drfile = test_path('testdata/test1.xlsx'), sheet = '_parameters', range = "A24:B24",
32+
guide <- read_guide(test_path("fixtures/guide_competition_1_0.yml"))
33+
expect_equal(read_keyvalue(drfile = test_path('fixtures/test1.xlsx'), sheet = '_parameters', range = "A24:B24",
3434
translate = FALSE, translations = guide$translations, atomicclass = "numeric"), expected_result_single)
3535
expected_result_multiple <- list('ic0.min' = 65, ic0.max=135)
36-
expect_equal(read_keyvalue(drfile = test_path('testdata/test1.xlsx'), sheet = '_parameters', range = "A27:B28",
36+
expect_equal(read_keyvalue(drfile = test_path('fixtures/test1.xlsx'), sheet = '_parameters', range = "A27:B28",
3737
translate = FALSE, translations = guide$translations, atomicclass = "numeric"), expected_result_multiple)
3838
})
3939

4040
test_that("reading multiple key-value pairs works", {
4141
expected_result <- list('studyID' = 'MyProject', 'exptID' = 'TTRfitc-020', 'plateID' = '1', 'instrID' = 'Instr1')
42-
expect_no_error(read_keyvalue(drfile = test_path('testdata/test1.xlsx'), sheet = 'description', range = "A10:B13"))
43-
guide <- read_guide(test_path("testdata/guide_competition_1_0.yml"))
44-
expect_equal(read_keyvalue(drfile = test_path('testdata/test1.xlsx'), sheet = 'description', range = "A10:B13", translate = TRUE,
42+
expect_no_error(read_keyvalue(drfile = test_path('fixtures/test1.xlsx'), sheet = 'description', range = "A10:B13"))
43+
guide <- read_guide(test_path("fixtures/guide_competition_1_0.yml"))
44+
expect_equal(read_keyvalue(drfile = test_path('fixtures/test1.xlsx'), sheet = 'description', range = "A10:B13", translate = TRUE,
4545
translations = guide$translations), expected_result)
4646
})
4747

4848
test_that("Reading cells works", {
4949
variables <- list(list(name = "spread.itm1", cell = "G6"),
5050
list(name = "spread.itm2", cell = "G33"))
5151
result <- list(spread.itm1 = "0.0463713477851084", spread.itm2 = "0.0154571159283695")
52-
expect_no_error(read_cells(drfile = test_path('testdata/test1.xlsx'), sheet = 'BGfluo', variables = variables))
53-
expect_equal(read_cells(drfile = test_path('testdata/test1.xlsx'), sheet = 'BGfluo', variables = variables), result)
52+
expect_no_error(read_cells(drfile = test_path('fixtures/test1.xlsx'), sheet = 'BGfluo', variables = variables))
53+
expect_equal(read_cells(drfile = test_path('fixtures/test1.xlsx'), sheet = 'BGfluo', variables = variables), result)
5454
})
5555

5656
test_that("reading a table works", {
57-
expect_no_error(read_table(drfile = test_path('testdata/test1.xlsx'), sheet = '_data', range = "A101:B111"))
57+
expect_no_error(read_table(drfile = test_path('fixtures/test1.xlsx'), sheet = '_data', range = "A101:B111"))
5858
})
5959

6060
test_that("Function read_data works", {
61-
guide <- read_guide(test_path("testdata/guide_competition_1_0.yml"))
62-
expect_no_error(read_data(drfile = test_path('testdata/test1.xlsx'), guide = guide))
63-
expect_no_error(read_data(drfile = test_path('testdata/test1.xlsx'), guide = test_path("testdata/guide_competition_1_0.yml")))
61+
guide <- read_guide(test_path("fixtures/guide_competition_1_0.yml"))
62+
expect_no_error(read_data(drfile = test_path('fixtures/test1.xlsx'), guide = guide))
63+
expect_no_error(read_data(drfile = test_path('fixtures/test1.xlsx'), guide = test_path("fixtures/guide_competition_1_0.yml")))
6464
})
6565

6666

6767
# test_that("Function read_data using guide with two plates returns two plates", {
68-
# guide <- read_guide(test_path("testdata/goodguides/guide_with_two_plates.yaml"))
69-
# result <- read_data(drfile = test_path('testdata/test1.xlsx'), guide = guide)
68+
# guide <- read_guide(test_path("fixtures/goodguides/guide_with_two_plates.yaml"))
69+
# result <- read_data(drfile = test_path('fixtures/test1.xlsx'), guide = guide)
7070
# expect_equal(length(result$platedata), 2)
7171
# })
7272

7373
# test_that("Function read_data using guide split table returns single table", {
74-
# # guide <- read_guide(test_path("testdata/goodguides/guide_with_split_table.yml"))
75-
# # result <- read_data(drfile = test_path('testdata/test2.xlsx'), guide = guide)
74+
# # guide <- read_guide(test_path("fixtures/goodguides/guide_with_split_table.yml"))
75+
# # result <- read_data(drfile = test_path('fixtures/test2.xlsx'), guide = guide)
7676
# # expect_equal(length(result$table), 1)
7777
# })
7878

7979
test_that("Version incompatibilities yield an error.", {
80-
guide <- read_guide(test_path("testdata/erroneousguides/conflicting_min_version.yml"))
81-
expect_error(read_data(drfile = test_path('testdata/test1.xlsx'), guide = guide))
82-
guide <- read_guide(test_path("testdata/erroneousguides/conflicting_max_version.yml"))
83-
expect_error(read_data(drfile = test_path('testdata/test1.xlsx'), guide = guide))
80+
guide <- read_guide(test_path("fixtures/erroneousguides/conflicting_min_version.yml"))
81+
expect_error(read_data(drfile = test_path('fixtures/test1.xlsx'), guide = guide))
82+
guide <- read_guide(test_path("fixtures/erroneousguides/conflicting_max_version.yml"))
83+
expect_error(read_data(drfile = test_path('fixtures/test1.xlsx'), guide = guide))
8484
})
8585

86+
# testing reading of dates
87+
test_that("Reading key-value pairs with different atomic classes yields correct results", {
88+
excel_file <- test_path("fixtures/test0.xlsx")
89+
sheet <- "kvpairs"
90+
expect_no_error(
91+
result <- read_keyvalue(
92+
drfile = excel_file, sheet = sheet, range = "A2:B4",
93+
translate = FALSE, atomicclass = c("character","character","numeric")
94+
)
95+
)
96+
expect_equal(result, list(char1 = "9.3", char2 = "test", num1 = 1.2))
97+
expect_no_error(
98+
result <- read_keyvalue(
99+
drfile = excel_file, sheet = sheet, range = "A7:B7",
100+
translate = FALSE, atomicclass = c("character")
101+
)
102+
)
103+
expect_equal(
104+
result, list(char1 = "9.3")
105+
)
106+
})

tests/testthat/test-utils.R

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,21 @@ test_that("function coerce works", {
4848
expect_equal(coerce("true", "logical"), TRUE)
4949
})
5050

51+
52+
# testing reading of dates
5153
test_that("Reading dates from an excel file yield correct dates", {
52-
excel_file <- test_path("testdata/dates_linux.xlsx")
53-
date1 <- readxl::read_excel(excel_file, sheet=1, range="A1:A2")
54-
date2 <- readxl::read_excel(excel_file, sheet=1, range="B1:B2")
55-
date3 <- readxl::read_excel(excel_file, sheet=1, range="C1:C2")
56-
expect_equal(coerce(date1 |> dplyr::pull(1), "date"), as.Date("1962-10-27"))
57-
expect_equal(coerce(date2 |> dplyr::pull(1), "date"), as.Date("1962-10-27"))
58-
expect_equal(coerce(date3 |> dplyr::pull(1), "date"), as.Date("1962-10-27"))
59-
date4 <- readxl::read_excel(excel_file, sheet=1, range="D1:D2")
60-
date5 <- readxl::read_excel(excel_file, sheet=1, range="E1:E2")
61-
date6 <- readxl::read_excel(excel_file, sheet=1, range="F1:F2")
62-
expect_equal(coerce(date4 |> dplyr::pull(1), "date"), as.Date("2025-04-01"))
63-
expect_equal(coerce(date5 |> dplyr::pull(1), "date"), as.Date("2025-04-01"))
64-
expect_equal(coerce(date6 |> dplyr::pull(1), "date"), as.Date("2025-04-01"))
54+
excel_file <- test_path("fixtures/test0.xlsx")
55+
sheet <- "dates"
56+
date1 <- readxl::read_excel(excel_file, sheet = sheet, col_names = "date", range = "B1:B1")
57+
date2 <- readxl::read_excel(excel_file, sheet = sheet, col_names = "date", range = "B2:B2")
58+
date3 <- readxl::read_excel(excel_file, sheet = sheet, col_names = "date", range = "B3:B3")
59+
expect_equal(coerce(date1 |> dplyr::pull(date), "date"), as.Date("1962-10-27"))
60+
expect_equal(coerce(date2 |> dplyr::pull(date), "date"), as.Date("1962-10-27"))
61+
expect_equal(coerce(date3 |> dplyr::pull(date), "date"), as.Date("1962-10-27"))
62+
date4 <- readxl::read_excel(excel_file, sheet = sheet, col_names = "date", range="B4:B4")
63+
date5 <- readxl::read_excel(excel_file, sheet = sheet, col_names = "date", range="B5:B5")
64+
date6 <- readxl::read_excel(excel_file, sheet = sheet, col_names = "date", range="B6:B6")
65+
expect_equal(coerce(date4 |> dplyr::pull(date), "date"), as.Date("2025-04-01"))
66+
expect_equal(coerce(date5 |> dplyr::pull(date), "date"), as.Date("2025-04-01"))
67+
expect_equal(coerce(date6 |> dplyr::pull(date), "date"), as.Date("2025-04-01"))
6568
})

0 commit comments

Comments
 (0)