У меня есть фрейм данных. Давайте позвоним ему bob
:
> head(bob)
phenotype exclusion
GSM399350 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399351 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399352 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399353 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399354 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399355 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
Я хотел бы объединить строки этого фрейма данных (это будет другой вопрос). Но посмотрите:
> class(bob$phenotype)
[1] "factor"
Bob
Столбцы являются факторами. Так, например:
> as.character(head(bob))
[1] "c(3, 3, 3, 6, 6, 6)" "c(3, 3, 3, 3, 3, 3)"
[3] "c(29, 29, 29, 30, 30, 30)"
Я не начинаю понимать это, но я предполагаю, что это индексы в уровнях факторов колонн (двора царя каратакуса) bob
? Не то, что мне нужно.
Странно, я могу пройти через столбцы bob
вручную, и сделать
bob$phenotype <- as.character(bob$phenotype)
который отлично работает И после некоторого набора я могу получить data.frame, столбцы которого являются символами, а не факторами. Итак, мой вопрос: как я могу сделать это автоматически? Как преобразовать data.frame с факторными столбцами в data.frame с символьными столбцами без необходимости вручную проходить через каждый столбец?
Бонусный вопрос: почему ручной подход работает?
bob
.Ответы:
Просто следую за Мэттом и Дирком. Если вы хотите воссоздать существующий фрейм данных без изменения глобального параметра, вы можете воссоздать его с помощью оператора apply:
Это преобразует все переменные в класс «персонаж», если вы хотите преобразовать только факторы, см . Решение Марека ниже .
Как отмечает @hadley, следующее является более лаконичным.
В обоих случаях
lapply
выводит список; однако, благодаря магическим свойствам R, использование[]
во втором случае сохраняет класс data.framebob
объекта, тем самым устраняя необходимость преобразования обратно в data.frameas.data.frame
с использованием аргументаstringsAsFactors = FALSE
.источник
type.convert
после приведения всех кcharacter
, а затемfactors
выполнитьcharacter
повторный возврат .bob[] <-
в примере илиbob <-
? первый хранит data.frame; вторая изменяет data.frame в список, удаляя имена строк. Я буду обновлять ответiris[] <- lapply(iris, function(x) if (is.factor(x)) as.character(x) else {x})
Заменить только факторы:
В пакете dplyr в версии 0.5.0
mutate_if
была введена новая функция :Пакетное мурлыканье от RStudio дает еще одну альтернативу:
источник
purrr
строка возвращает список, а не adata.frame
!i
векторcolnames()
.Глобальный вариант
может быть что-то, что вы хотите установить
FALSE
в ваших файлах запуска (например, ~ / .Rprofile). Пожалуйста, смотритеhelp(options)
.источник
Если вы понимаете, как хранятся факторы, вы можете избежать использования основанных на применении функций для этого. Что вовсе не означает, что применяемые решения не работают хорошо.
Факторы структурированы как числовые индексы, привязанные к списку «уровней». Это можно увидеть, если вы преобразуете коэффициент в число. Так:
Числа, возвращаемые в последней строке, соответствуют уровням фактора.
Обратите внимание, что
levels()
возвращает массив символов. Вы можете использовать этот факт для простого и компактного преобразования коэффициентов в строки или числа, например:Это также работает для числовых значений, при условии, что вы переносите выражение в
as.numeric()
.источник
as.character(f)
лучше в удобочитаемости и эффективностиlevels(f)[as.numeric(f)]
. Если вы хотите быть умным, вы можете использоватьlevels(f)[f]
вместо этого. Обратите внимание, что при преобразовании коэффициента с числовыми значениями вы получаете некоторую выгоду отas.numeric(levels(f))[f]
, например, превышения,as.numeric(as.character(f))
но это потому, что вам нужно только преобразовать уровни в числовые, а затем в подмножество.as.character(f)
просто отлично, как есть.Если вам нужен новый фрейм данных, в
bobc
котором каждый фактор-векторbobf
преобразуется в символьный вектор, попробуйте следующее:Если затем вы хотите преобразовать его обратно, вы можете создать логический вектор, столбцы которого являются факторами, и использовать его для выборочного применения коэффициента.
источник
Я обычно делаю эту функцию отдельно от всех своих проектов. Быстро и просто.
источник
Другой способ - конвертировать его с помощью apply.
И лучше (предыдущий класс «матрица»)
источник
as.data.frame(lapply(...
Обновление: вот пример чего-то, что не работает. Я думал, что будет, но я думаю, что опция stringsAsFactors работает только на символьных строках - она оставляет факторы в покое.
Попробуй это:
В общем, всякий раз, когда у вас возникают проблемы с факторами, которые должны быть символами, есть
stringsAsFactors
место, где вам помогут (в том числе глобальные настройки).источник
bob
для начала (но не по факту).Или вы можете попробовать
transform
:Просто убедитесь, что все факторы, которые вы хотели бы преобразовать в характер.
Или вы можете сделать что-то вроде этого и убить всех вредителей одним ударом:
Это не очень хорошая идея, чтобы засунуть данные в код, подобный этому, я мог бы выполнить
sapply
часть отдельно (на самом деле, сделать это гораздо проще), но вы понимаете, что я не проверял код, потому что Я не дома, поэтому я надеюсь, что это работает! знак равноЭтот подход, однако, имеет недостаток ... вы должны реорганизовать столбцы впоследствии, в то время как
transform
вы можете делать все что угодно, но за счет "написания кода в стиле пешехода" ...Так что есть ... =)
источник
В начале вашего фрейма данных включите,
stringsAsFactors = FALSE
чтобы игнорировать все недоразумения.источник
Если бы вы использовали
data.table
package для операций над data.frame, то проблемы нет.Если в вашем наборе данных уже есть столбцы факторов и вы хотите преобразовать их в символы, вы можете сделать следующее.
источник
In [<-.data.table(*tmp*, sapply(bob, is.factor), : Coerced 'character' RHS to 'double' to match the column's type. Either change the target column to 'character' first (by creating a new 'character' vector length 1234 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'double' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please.
проще исправить DF и воссоздать DT.Это работает для меня - я, наконец, понял, один вкладыш
источник
Эта функция делает свое дело
источник
Может быть, более новый вариант?
источник
Вы должны использовать
convert
вhablar
котором дает читаемый синтаксис, совместимый сtidyverse
каналами:что дает вам:
источник
С
dplyr
загруженным пакетомесли вы хотите
phenotype
конкретно изменить -column.источник
Это работает, преобразовывая все в символ, а затем из числа в число:
Адаптировано из: Получить типы столбцов таблицы Excel автоматически
источник