R | 将 data.frame 转换为“纯文本”

4
我需要将一个 data.frame 对象转换为纯文本(类似于在控制台上的 print 输出)。
到目前为止,我已经使用了 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|
2个回答

4

看了一下print.data.frame函数后,我敢说以下可能是更好的解决方案(格式更好,几乎是一个经过充分测试的内置函数的相同代码)

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"));
    }
}

4

我认为使用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|

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接