Я использовал очень простой метод для проверки строки, как это действительный JSON или нет.
function testJSON(text){
if (typeof text!=="string"){
return false;
}
try{
JSON.parse(text);
return true;
}
catch (error){
return false;
}
}
Результат с действительной строкой JSON:
var input='["foo","bar",{"foo":"bar"}]';
testJSON(input); // returns true;
Результат с простая строка;
var input='This is not a JSON string.';
testJSON(input); // returns false;
Результат с объектом:
var input={};
testJSON(input); // returns false;
Результат с нулевым входом:
var input=null;
testJSON(input); // returns false;
Последний возвращает false, тип нулевых переменных - объект.
Это работает каждый раз. :)
Просто после Мэтта и Дирка. Если вы хотите воссоздать существующий фрейм данных без изменения глобальной опции, вы можете воссоздать его с помощью оператора apply:
bob <- data.frame(lapply(bob, as.character), stringsAsFactors=FALSE)
Это преобразует все переменные в класс «character», если вы хотите только коэффициенты преобразования, см. решение Марека ниже .
Как указывает @hadley, следующее краткое.
bob[] <- lapply(bob, as.character)
В обоих случаях lapply
выводит список; однако из-за магических свойств R использование []
во втором случае сохраняет класс data.frame объекта bob
, тем самым устраняя необходимость преобразования обратно в data.frame с использованием as.data.frame
с аргумент stringsAsFactors = FALSE
.
Или вы можете попробовать transform
:
newbob <- transform(bob, phenotype = as.character(phenotype))
Просто не забудьте указать все факторы, которые вы хотели бы преобразовать в символ.
Или вы можете сделать что-то вроде это и убить всех вредителей одним ударом:
newbob_char <- as.data.frame(lapply(bob[sapply(bob, is.factor)], as.character), stringsAsFactors = FALSE)
newbob_rest <- bob[!(sapply(bob, is.factor))]
newbob <- cbind(newbob_char, newbob_rest)
Это not хорошая идея перекодировать данные в код, как это, я мог бы сделать часть sapply
отдельно ( на самом деле, это гораздо проще сделать так), но вы понимаете ... Я не проверял код, потому что меня нет дома, поэтому я надеюсь, что это сработает! =)
Этот подход, однако, имеет недостаток ... вы должны реорганизовать столбцы впоследствии, а с помощью transform
вы можете делать все, что захотите, но по цене «пешеходный стиль - кодовое " ...
Итак, там ... =)
Я обычно делаю эту функцию отдельно от всех моих проектов. Быстро и просто.
unfactorize <- function(df){
for(i in which(sapply(df, class) == "factor")) df[[i]] = as.character(df[[i]])
return(df)
}
Эта функция выполняет трюк
df <- stacomirtools::killfactor(df)
Другой способ - преобразовать его, используя apply
bob2 <- apply(bob,2,as.character)
И лучший (предыдущий - это «матрица» класса)
bob2 <- as.data.frame(as.matrix(bob),stringsAsFactors=F)
as.data.frame(lapply(...
– aL3xa
17 May 2010 в 19:08
Если вы будете использовать пакет data.table
для операций над data.frame, тогда проблемы нет.
library(data.table)
dt = data.table(col1 = c("a","b","c"), col2 = 1:3)
sapply(dt, class)
# col1 col2
#"character" "integer"
Если у вас уже есть столбцы факторов в вашем наборе данных и вы хотите преобразовать их в символ, вы можете сделать следующее.
library(data.table)
dt = data.table(col1 = factor(c("a","b","c")), col2 = 1:3)
sapply(dt, class)
# col1 col2
# "factor" "integer"
upd.cols = sapply(dt, is.factor)
dt[, names(dt)[upd.cols] := lapply(.SD, as.character), .SDcols = upd.cols]
sapply(dt, class)
# col1 col2
#"character" "integer"
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.
– Matt Chambers
3 August 2016 в 17:49
Я знаю, что этот ответ немного запоздал, но если вы понимаете, как сохраняются факторы, вы можете избежать использования прикладных функций для достижения этого. Это вовсе не означает, что прикладные решения не работают.
Факторы структурированы как числовые индексы, привязанные к списку «уровней». Это можно увидеть, если вы преобразуете коэффициент в числовой. Итак:
> fact <- as.factor(c("a","b","a","d")
> fact
[1] a b a d
Levels: a b d
> as.numeric(fact)
[1] 1 2 1 3
Цифры, возвращаемые в последней строке, соответствуют уровням фактора.
> levels(fact)
[1] "a" "b" "d"
Обратите внимание, что levels()
возвращает массив символов. Вы можете использовать этот факт для легкого и компактного преобразования факторов в строки или числовые значения следующим образом:
> fact_character <- levels(fact)[as.numeric(fact)]
> fact_character
[1] "a" "b" "a" "d"
Это также работает для числовых значений, если вы завершаете свое выражение в as.numeric()
.
> num_fact <- factor(c(1,2,3,6,5,4))
> num_fact
[1] 1 2 3 6 5 4
Levels: 1 2 3 4 5 6
> num_num <- as.numeric(levels(num_fact)[as.numeric(num_fact)])
> num_num
[1] 1 2 3 6 5 4
Для замены только факторов:
i <- sapply(bob, is.factor)
bob[i] <- lapply(bob[i], as.character)
В пакете dplyr в версии 0.5.0 была введена новая функция mutate_if
:
library(dplyr)
bob %>% mutate_if(is.factor, as.character) -> bob
Пакет purrr из RStudio дает другую альтернативу:
library(purrr)
library(dplyr)
bob %>% map_if(is.factor, as.character) %>% as_data_frame -> bob
(помните, что это свежий пакет)
Обновление: Вот пример того, что не работает. Я думал, что это произойдет, но я думаю, что параметр strAsAsFactors работает только с символьными строками - он оставляет только факторы.
Попробуйте следующее:
bob2 <- data.frame(bob, stringsAsFactors = FALSE)
Вообще говоря, у вас возникают проблемы с факторами, которые должны быть персонажами, есть где-то stringsAsFactors
, чтобы помочь вам (включая глобальную настройку).
bob
для начала (но не после факта).
– Shane
17 May 2010 в 18:18
Глобальная опция
stringsAsFactors: параметр по умолчанию для аргументов data.frame и read.table.
blockquote>может быть чем-то, что вы хотите установить на
FALSE
в ваших файлах запуска (например, ~ / .Rprofile). См.help(options)
.
Если вам нужен новый фрейм данных bobc
, где каждый вектор фактора в bobf
преобразуется в вектор символов, попробуйте это:
bobc <- rapply(bobf, as.character, classes="factor", how="replace")
Если вы то вы хотите преобразовать его обратно, вы можете создать логический вектор, столбцы которого являются факторами, и использовать его для выборочного применения фактора
f <- sapply(bobf, class) == "factor"
bobc[,f] <- lapply(bobc[,f], factor)
В начале вашего фрейма данных включите stringsAsFactors = FALSE
, чтобы игнорировать все недоразумения.
Это работает для меня - я, наконец, вычислил один лайнер
df <- as.data.frame(lapply(df,function (y) if(class(y)=="factor" ) as.character(y) else y),stringsAsFactors=F)
type.convert
после того, как все было добавлено кcharacter
, а затем сноваfactors
снова вернуться кcharacter
. – Shane 17 May 2010 в 19:56bob[] <-
в примере илиbob <-
?; первый хранит data.frame; второй изменяет файл data.frame на список, отбрасывая имена розеток. Я обновлю ответ – David LeBauer 11 December 2014 в 22:51iris[] <- lapply(iris, function(x) if (is.factor(x)) as.character(x) else {x})
– Stefan F 5 July 2017 в 18:09