Я получал эту ошибку с раскадровки. Вышеупомянутое решение, похоже, не было проблемой, поэтому я в конечном итоге удалил контроллер представления и снова добавил его (и, конечно, повторно подключил segue и переназначил класс), который его исправил. Я не знаю, что это было на самом деле, но я переименовал соответствующий класс контроллера вида незадолго до этого, так что, возможно, это что-то укусило.
Все, что вам нужно сделать, это снова применить множитель () к вашей переменной после подмножества:
> subdf$letters
[1] a b c
Levels: a b c d e
subdf$letters <- factor(subdf$letters)
> subdf$letters
[1] a b c
Levels: a b c
ИЗМЕНИТЬ
Пример примера с параметрами:
factor(ff) # drops the levels that do not occur
Для удаления уровней из всех столбцов факторов в кадре данных вы можете использовать:
subdf <- subset(df, numbers <= 3)
subdf[] <- lapply(subdf, function(x) if(is.factor(x)) factor(x) else x)
Вот еще один способ, который, я считаю, эквивалентен подходу factor(..)
:
> df <- data.frame(let=letters[1:5], num=1:5)
> subdf <- df[df$num <= 3, ]
> subdf$let <- subdf$let[ , drop=TRUE]
> levels(subdf$let)
[1] "a" "b" "c"
Для полноты, теперь есть fct_drop
в пакете forcats
http://forcats.tidyverse.org/reference/fct_drop.html .
Он отличается от droplevels
тем, как он имеет дело с NA
:
f <- factor(c("a", "b", NA), exclude = NULL)
droplevels(f)
# [1] a b <NA>
# Levels: a b <NA>
forcats::fct_drop(f)
# [1] a b <NA>
# Levels: a b
Я написал служебные функции для этого. Теперь, когда я знаю о drop.levels gdata, он выглядит довольно похожим. Здесь они (из здесь ):
present_levels <- function(x) intersect(levels(x), x)
trim_levels <- function(...) UseMethod("trim_levels")
trim_levels.factor <- function(x) factor(x, levels=present_levels(x))
trim_levels.data.frame <- function(x) {
for (n in names(x))
if (is.factor(x[,n]))
x[,n] = trim_levels(x[,n])
x
}
здесь есть способ сделать это
varFactor <- factor(letters[1:15])
varFactor <- varFactor[1:5]
varFactor <- varFactor[drop=T]
Очень интересная нить, мне особенно понравилась идея просто подставить подзаголовок снова. Раньше у меня была аналогичная проблема, и я просто перешел к символу, а затем вернулся к коэффициенту.
df <- data.frame(letters=letters[1:5],numbers=seq(1:5))
levels(df$letters)
## [1] "a" "b" "c" "d" "e"
subdf <- df[df$numbers <= 3]
subdf$letters<-factor(as.character(subdf$letters))
Это известная проблема, и одно возможное решение предоставляется drop.levels()
в пакете gdata , где ваш пример становится
> drop.levels(subdf)
letters numbers
1 a 1
2 b 2
3 c 3
> levels(drop.levels(subdf)$letters)
[1] "a" "b" "c"
Существует также dropUnusedLevels
в пакете Hmisc . Однако он работает только путем изменения оператора подмножества [
и здесь неприменим.
В качестве следствия прямой подход на основе столбца является простым as.factor(as.character(data))
:
> levels(subdf$letters)
[1] "a" "b" "c" "d" "e"
> subdf$letters <- as.factor(as.character(subdf$letters))
> levels(subdf$letters)
[1] "a" "b" "c"
reorder
функции drop.levels
стоит упомянуть: если вам нужно сохранить исходный порядок ваших факторов, используйте его с FALSE
значением.
– daroczig
17 January 2011 в 12:31
Если вы не хотите этого поведения, не используйте факторы, используйте вместо него векторы символов. Я думаю, что это имеет больше смысла, чем исправление. Попробуйте выполнить следующие действия перед загрузкой данных с помощью read.table
или read.csv
:
options(stringsAsFactors = FALSE)
Недостатком является то, что вы ограничены алфавитным порядком. (переупорядочить ваш друг для сюжетов)
Глядя на код droplevels
методов в источнике R, вы можете видеть , он обтекает функцию factor
. Это означает, что вы можете в основном воссоздать столбец с функцией factor
. Ниже data.table способ сбросить уровни из всех столбцов факторов.
library(data.table)
dt = data.table(letters=factor(letters[1:5]), numbers=seq(1:5))
levels(dt$letters)
#[1] "a" "b" "c" "d" "e"
subdt = dt[numbers <= 3]
levels(subdt$letters)
#[1] "a" "b" "c" "d" "e"
upd.cols = sapply(subdt, is.factor)
subdt[, names(subdt)[upd.cols] := lapply(.SD, factor), .SDcols = upd.cols]
levels(subdt$letters)
#[1] "a" "b" "c"
data.table
будет похож на for (j in names(DT)[sapply(DT, is.factor)]) set(DT, j = j, value = factor(DT[[j]]))
– David Arenburg
24 January 2016 в 14:24
[.data.table
только один раз
– jangorecki
30 November 2016 в 14:25
Это неприятно. Так я обычно делаю это, чтобы не загружать другие пакеты:
levels(subdf$letters)<-c("a","b","c",NA,NA)
, который получает вас:
> subdf$letters
[1] a b c
Levels: a b c
Обратите внимание, что новые уровни заменят все, что занимает их индекс в старые значения (subdf $ letters), поэтому что-то вроде:
levels(subdf$letters)<-c(NA,"a","c",NA,"b")
не будет работать.
Это, очевидно, не идеально, когда у вас много уровней, но для Несколько, это быстро и легко.
Поскольку R версии 2.12, есть функция droplevels()
.
levels(droplevels(subdf$letters))
mydf <- droplevels(mydf)
решение, предложенное Романом Луштриком и Томми О'Деллом ниже. – Johan 9 May 2014 в 11:41rlm
действительно идет не так, когда ваш data.frame содержит факторы, которые содержат уровни без данных. Вы получите сообщение об ошибке: уникальные приемы не реализованы в 'rlm'. В большинстве случаев ваша матрица не является единственной, это именно эта проблема. – Matt Bannert 19 June 2014 в 15:31