网络包更改了字符向量摘要的行为,打破了 summary.data.frame(打印所有值,以 NULL: 开头)
Network package changes behaviour of summary for character vectors, breaking summary.data.frame (all values are printed, preceded by NULL: )
加载 network
包后,summary.data.frame
函数出现问题:如果出现 class "character"
列,而不是通常的输出, summary 将打印 all 行的值,并在前面加上 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"
网络包定义了一个summary.character
函数,它简单地向字符对象添加一个"summary.character"
class,这样它的打印调用network::print.summary.character
,它产生table 最多 10
个最常见的值。对象本身没有变化,所以它的 names
是 NULL
。
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.character
的输出,sms
实际上是整列,而 names(sms)
是 NULL
,因此出现问题。
问题的核心原因在于summary.character
returns 原始对象,而不是其委托给print.summary.character
的摘要表示。 summary.data.frame
只是将其与其他摘要一起粘贴,转储整个专栏。
任何关于如何在不深入研究 network
的源代码的情况下解决此问题的想法将不胜感激。
我找到了一个解决方法,不幸的是,它通过定义一个函数 format.summary.character
来恢复内部代码的预期行为,从而更多地涉及 "polluting" 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
控制,但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
##
加载 network
包后,summary.data.frame
函数出现问题:如果出现 class "character"
列,而不是通常的输出, summary 将打印 all 行的值,并在前面加上 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"
网络包定义了一个summary.character
函数,它简单地向字符对象添加一个"summary.character"
class,这样它的打印调用network::print.summary.character
,它产生table 最多 10
个最常见的值。对象本身没有变化,所以它的 names
是 NULL
。
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.character
的输出,sms
实际上是整列,而 names(sms)
是 NULL
,因此出现问题。
问题的核心原因在于summary.character
returns 原始对象,而不是其委托给print.summary.character
的摘要表示。 summary.data.frame
只是将其与其他摘要一起粘贴,转储整个专栏。
任何关于如何在不深入研究 network
的源代码的情况下解决此问题的想法将不胜感激。
我找到了一个解决方法,不幸的是,它通过定义一个函数 format.summary.character
来恢复内部代码的预期行为,从而更多地涉及 "polluting" 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
控制,但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
##