2017-08-04 86 views
1

我需要一個data.frame對象「轉換」成純文本(如print輸出到控制檯上。R | data.frame爲「純文本」

到目前爲止,我創建了以下功能(使用stringr包),但我不知道是否已實施的功能或更有效的方法存在:

toString.data.frame = function(object, ...) { 
    maxLen = max(
       stringr::str_length(apply(object, c(1,2), as.character)), 
       stringr::str_length(names(object)) 
       ); 

    # data-frame to character matrix 
    txt = apply(object, c(1,2), stringr::str_pad, width=maxLen+5, side="left"); 
    # concatenate the columns 
    txt = apply(txt, 1, paste, collapse=""); 
    # concatenate the rows 
    txt = paste(txt, collapse="\n"); 
    # add column names 
    txt = paste(# concatenate header and body 
      paste(# concatenate all the headers 
       stringr::str_pad(# add 5 spaces on the left of each header 
        stringr::str_pad(names(object), width=maxLen, side="right") # fill each header 
        , width=maxLen+5, side="left") 
       , collapse="") 
      , txt 
      , sep="\n"); 

    return(txt); 
} 

我添加一些可運行代碼以及一個輸出實例(每個輸出行由分隔「|」)

df = data.frame(hello=rnorm(1:15), world=rnorm(1:15)); 
cat(toString(object), "\n"); 


|   a      b    |  
|  0.217785930312173  1.35892062758937| 
|  -0.0529272009376736  -1.3537444650507| 
|  -0.0914533595349014  -0.283164123247757| 
|  0.209099248751634  -0.994596208802379| 
|  1.41207193727609  0.754568758899429| 
|  0.0271570788346636  0.722728545001598| 
|  1.09160395973882  -0.466194711071017| 
|  -0.676012596015548  0.247534965195453| 
|  0.36022565974381  -0.318822054653857| 
|  0.330251755314496  -0.379818935427323| 
|  1.29858423625996  0.393100959746072| 
|  1.79061048596737  0.124484229714237| 
|  -0.636849202004066  -1.48651181772674| 
|  1.08795175312078  0.231693241998673| 
|  -0.810214549466222  -0.753200696904484| 

回答

1

我認爲它會更簡單的使用sinktextConnection,以及一些手動格式化你想要的效果。

df = data.frame(hello=rnorm(1:15), world=rnorm(1:15)); 
tc <- textConnection("str", "w") 
sink(tc) # divert output to tc connection 
print(df) # print in str string instead of console 
sink()  # set the output back to console 
close(tc) # close connection 
str <- substr(str,floor(length(str)/10)+3,nchar(str[1])) # we get rid of the row numbers that come with print 
str <- paste0("| ",str,"|",collapse="\n")  # we build a proper unique string with your pipes and new lines 
cat(str) 
# |  hello  world| 
# | 1.35547838 0.69280925| 
# | 0.61364635 1.84942722| 
# | -0.23441769 0.10034022| 
# | 1.73325659 -0.22303366| 
# | -0.65542783 -0.47574465| 
# | -0.87341058 -0.63579176| 
# | 0.04449579 0.36899672| 
# | -1.00486219 1.25508269| 
# | -0.23235707 1.18740340| 
# | -0.46296889 0.88100960| 
# | 0.52494728 0.20217947| 
# | 0.94017525 0.01272363| 
# | -0.09997728 0.22612848| 
# | -0.04388133 -0.49271157| 
# | -1.09953287 -0.27971771| 
1

具有看看print.data.frame功能後,我敢說下面可能是一個更好的解決方案(更好的格式,它幾乎是一個屢試不爽的bult,在功能相同的代碼)

toString.data.frame = function (object, ..., digits=NULL, quote=FALSE, right=TRUE, row.names=TRUE) { 
    nRows = length(row.names(object)); 
    if (length(object)==0) { 
     return(paste(
        sprintf(ngettext(nRows, "data frame with 0 columns and %d row", "data frame with 0 columns and %d rows") 
          , nRows) 
        , "\\n", sep = "") 
       ); 
    } else if (nRows==0) { 
     return(gettext("<0 rows> (or 0-length row.names)\\n")); 
    } else { 
     # get text-formatted version of the data.frame 
     m = as.matrix(format.data.frame(object, digits=digits, na.encode=FALSE)); 
     # define row-names (if required) 
     if (isTRUE(row.names)) { 
      rowNames = dimnames(object)[[1]]; 
      if(is.null(rowNames)) { 
       # no row header available -> use row numbers 
       rowNames = as.character(1:NROW(m)); 
      } 
      # add empty header (used with column headers) 
      rowNames = c("", rowNames); 
     } 
     # add column headers 
     m = rbind(dimnames(m)[[2]], m); 
     # add row headers 
     m = cbind(rowNames, m); 
     # max-length per-column 
     maxLen = apply(apply(m, c(1,2), stringr::str_length), 2, max, na.rm=TRUE); 

     # add right padding 
     ## t is needed because "If each call to FUN returns a vector of length n, then apply returns an array of dimension c(n, dim(X)[MARGIN])" 
     m = t(apply(m, 1, stringr::str_pad, width=maxLen, side="right")); 
     m = t(apply(m, 1, stringr::str_pad, width=maxLen+3, side="left")); 
     # merge columns 
     m = apply(m, 1, paste, collapse=""); 
     # merge rows (and return) 
     return(paste(m, collapse="\n")); 
    } 
}