Сетевой пакет изменяет поведение сводки для символьных векторов, нарушая summary.data.frame (все значения печатаются, с предшествующим NULL:)

После загрузки network У меня проблема с summary.data.frame функция: если столбец класса "character" присутствует, вместо обычного вывода, резюме будет печатать значения из всех строк, с добавлением 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" класс к объекту персонажа, так что его вызовы печати network::print.summary.character, который производит таблицу до 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 возвращает исходный объект вместо его сводного представления, которое делегировано print.summary.character, summary.data.frame просто вставьте его вместе с другими аннотациями, сбросив весь столбец.

Любая идея о том, как это исправить, не углубляясь в источники network будет очень признателен.

1 ответ

Решение

Я нашел решение этой проблемы, к сожалению, это включает в себя "загрязнение" пространства имен R немного больше (чтобы цитировать комментарии @steveb), определяя функцию format.summary.character который восстанавливает ожидаемое поведение кода внутри 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.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  
## 
Другие вопросы по тегам