3

I'm fetching data from an online database (REDCap) via API and the data gets delivered in as comma separated string like this,

RAW.API <- structure("id,event_arm,name,dob,pushed_text,pushed_calc,complete\n\"01\",\"event_1_arm_1\",\"John\",\"1979-05-01\",\"\",\"\",2\n\"01\",\"event_2_arm_1\",\"John\",\"2012-09-02\",\"abc\",\"123\",1\n\"01\",\"event_3_arm_1\",\"John\",\"2012-09-10\",\"\",\"\",2\n\"02\",\"event_1_arm_1\",\"Mary\",\"1951-09-10\",\"def\",\"456\",2\n\"02\",\"event_2_arm_1\",\"Mary\",\"1978-09-12\",\"\",\"\",2\n", "`Content-Type`" = structure(c("text/html", "utf-8"), .Names = c("", "charset")))

I have this script that nicely parses it into a data frame,

(df <- read.table(file = textConnection(RAW.API), header = TRUE, 
sep = ",", na.strings = "", stringsAsFactors = FALSE))
  id     event_arm name        dob pushed_text pushed_calc complete
1  1 event_1_arm_1 John 1979-05-01        <NA>          NA        2
2  1 event_2_arm_1 John 2012-09-02         abc         123        1
3  1 event_3_arm_1 John 2012-09-10        <NA>          NA        2
4  2 event_1_arm_1 Mary 1951-09-10         def         456        2
5  2 event_2_arm_1 Mary 1978-09-12        <NA>          NA        2

I then do some calculations and write them to pushed_text and pushed_calc whereafter I need to format the data back to the messy comma separated structure it came in.

I imagine something like this,

API.back <- `some magic command`(df, ...)

identical(RAW.API, API.back)
[1] TRUE

Some command that can format my data from the data frame I made, df, back to the structure that the raw API-object came in, RAW.API.

Any help would be very appreciated.

wibeasley
  • 5,000
  • 3
  • 34
  • 62
Eric Fail
  • 8,191
  • 8
  • 72
  • 128

1 Answers1

3

This seems to work:

some_magic <- function(df) {
    ## Replace NA with "", converting column types as needed
    df[] <- lapply(df, function(X) {
                if(any(is.na(X))) {X[is.na(X)] <- ""; X} else {X}
            })

    ## Print integers in first column as 2-digit character strings
    ## (DO NOTE: Hardwiring the number of printed digits here is probably
    ## inadvisable, though needed to _exactly_ reconstitute RAW.API.) 
    df[[1]] <- sprintf("%02.0f", df[[1]])

    ## Separately build header and table body, then suture them together 
    l1 <- paste(names(df), collapse=",")
    l2 <- capture.output(write.table(df, sep=",", col.names=FALSE, 
                                     row.names=FALSE))
    out <- paste0(c(l1, l2, ""), collapse="\n")

    ## Reattach attributes
    att <- list("`Content-Type`" = structure(c("text/html", "utf-8"), 
                .Names = c("", "charset")))
    attributes(out) <- att
    out
}

identical(some_magic(df), RAW.API)
# [1] TRUE
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • I am very impressed by the magic, but something seem to be missing. It is as there is an `}` or an `)` missing somewhere. Currently trying to figure it out. – Eric Fail Sep 17 '12 at 22:33
  • 1
    @EricFail -- So there was! It's now fixed and should work for you too. – Josh O'Brien Sep 18 '12 at 00:26