R“data.frame to”;纯文本“;
我需要将R“data.frame to”;纯文本“;,r,dataframe,text,R,Dataframe,Text,我需要将data.frame对象“转换”为纯文本(如print输出到控制台) 到目前为止,我创建了以下函数(使用stringr包),但我想知道是否存在已经实现的函数或更有效的方法: toString.data.frame = function(object, ...) { maxLen = max( stringr::str_length(apply(object, c(1,2), as.character)), stri
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);
}
我添加了一些可运行代码以及一个输出示例(每个输出行由“|”分隔)
在看了
print.data.frame
函数之后,我敢说下面可能是一个更好的解决方案(更好的格式,它几乎与经过良好测试的bult-in函数的代码相同)
toString.data.frame=函数(对象,…,数字=NULL,引号=FALSE,右=TRUE,行.名称=TRUE){
nRows=长度(行名称(对象));
如果(长度(对象)==0){
返回(粘贴)(
sprintf(ngettext(nRows,“包含0列和%d行的数据框”,“包含0列和%d行的数据框”)
,nRows)
,“\\n”,sep=“”)
);
}否则如果(nRows==0){
return(gettext(“(或0-length row.names)\\n”);
}否则{
#获取data.frame的文本格式版本
m=as.matrix(format.data.frame(object,digits=digits,na.encode=FALSE));
#定义行名称(如果需要)
如果(isTRUE(行名称)){
rowNames=dimnames(对象)[[1]];
如果(is.null(rowNames)){
#没有可用的行标题->使用行号
rowNames=as.character(1:NROW(m));
}
#添加空标题(与列标题一起使用)
rowNames=c(“,rowNames”);
}
#添加列标题
m=rbind(dimnames(m)[[2]],m);
#添加行标题
m=cbind(行名,m);
#每列的最大长度
maxLen=apply(apply(m,c(1,2),stringr::str_length),2,max,na.rm=TRUE);
#添加正确的填充
##t是必需的,因为“如果每个对FUN的调用返回一个长度为n的向量,那么apply返回一个维数为c(n,dim(X)[MARGIN])的数组。”
m=t(应用(m,1,stringr::str_pad,width=maxLen,side=“right”);
m=t(应用(m,1,stringr::str_pad,width=maxLen+3,side=“left”);
#合并列
m=应用(m,1,粘贴,折叠=”);
#合并行(并返回)
返回(粘贴(m,collapse=“\n”);
}
}
我认为使用sink
和textConnection
会更简单,还需要一些手动格式化来达到您想要的效果
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|
df=data.frame(hello=rnorm(1:15),world=rnorm(1:15));
tc
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"));
}
}
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|