2

加载network包后,summary.data.frame函数出现问题:如果存在类列"character",而不是通常的输出,summary 将打印所有行的值,前缀为NULL:. 这是一个玩具示例:

test <- data.frame(a=c("some", "char", "vector", "with", 
                       "many", "many", "words"),
                   b=1:7, stringsAsFactors = FALSE)

# Expected behaviour

summary(test$a)

##    Length     Class      Mode 
##         7 character character

summary(test)

##       a                   b      
##  Length:7           Min.   :1.0  
##  Class :character   1st Qu.:2.5  
##  Mode  :character   Median :4.0  
##                     Mean   :4.0  
##                     3rd Qu.:5.5  
##                     Max.   :7.0

library("network")

## network: Classes for Relational Data
## Version 1.13.0 created on 2015-08-31.
## ...

# Behavior after loading network:

summary(test$a)

##   char   many   some vector   with  words 
##      1      2      1      1      1      1

summary(test)

##     a                b      
##  NULL:some     Min.   :1.0  
##  NULL:char     1st Qu.:2.5  
##  NULL:vector   Median :4.0  
##  NULL:with     Mean   :4.0  
##  NULL:many     3rd Qu.:5.5  
##  NULL:many     Max.   :7.0  
##  NULL:words

请注意,输出包括字符向量的所有元素,包括重复项,因此您会得到 1000 行的 1000 行摘要,这会使摘要函数无法使用。分离网络包后,此行为会一直存在,直到重新启动新的 R 会话。

出了什么问题:通常UseMethod("summary")用于字符向量调用summary.default,它产生正常的输出,它有names.

summary.default(test$a)

##    Length     Class      Mode 
##         7 character character

names(summary.default(test$a))

## [1] "Length" "Class"  "Mode"

network 包定义了一个summary.character函数,它简单地将一个"summary.character"类添加到字符对象中,以便它的 print 调用network::print.summary.character,它生成具有10最常见值的表。对象本身是不变的,所以它namesNULL

summary.character

## function (object, ...) 
## {
##     class(object) <- c("summary.character", class(object))
##     object
## }
## <environment: namespace:network>

summary.character(test$a)

##   char   many   some vector   with  words 
##      1      2      1      1      1      1

names(summary.character(test$a))

## NULL

class(summary.character(test$a))

## [1] "summary.character" "character"

length(summary.character(test$a))

## [1] 7

as.character(summary.character(test$a))

## [1] "some"   "char"   "vector" "with"   "many"   "many"   "words"

麻烦来自以下三行summary.data.frame

        sms <- format(sms, digits = digits)
        lbs <- format(names(sms))
        sms <- paste0(lbs, ":", sms, "  ")

它在列的for循环内,当前列sms的输出在哪里。summary对于 的输出summary.charactersms实际上是整个列,并且names(sms)NULL,因此是问题所在。

问题的核心原因是summary.character返回原始对象,而不是委托给print.summary.character. summary.data.frame只需将其与其他摘要一起粘贴,即可倾倒整列。

任何关于如何在不深入研究来源的情况下解决此问题的想法network将不胜感激。

4

1 回答 1

0

format.summary.character我发现了一个转机,不幸的是,它通过定义一个函数来恢复内部代码的预期行为,从而更多地“污染” R 命名空间(引用@steveb 的评论)summary.data.frame。该功能的灵感来自format.factor

format.summary.character <- function(x, ...) {
    s <- summary.default(as.character(x), ...)
    format(structure(as.character(s), names = names(s), dim = dim(s), 
                     dimnames = dimnames(s)), ...)
}

定义此函数后,字符向量的summary 的输出仍由 控制summary.character,但for 的输出summary.data.frame恢复正常。

summary(test$a) # still calling summary.character

##   char   many   some vector   with  words 
##      1      2      1      1      1      1

summary(test)   # back to normal

##       a                   b      
##  Length:7           Min.   :1.0  
##  Class :character   1st Qu.:2.5  
##  Mode  :character   Median :4.0  
##                     Mean   :4.0  
##                     3rd Qu.:5.5  
##                     Max.   :7.0  
## 
于 2017-06-10T11:03:38.270 回答