преобразовать подмножество данных из символа в числовое [дубликат]

Я использовал очень простой метод для проверки строки, как это действительный 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, тип нулевых переменных - объект.

Это работает каждый раз. :)

276
задан GSee 11 January 2013 в 00:26
поделиться

13 ответов

Просто после Мэтта и Дирка. Если вы хотите воссоздать существующий фрейм данных без изменения глобальной опции, вы можете воссоздать его с помощью оператора 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.

299
ответ дан Community 18 August 2018 в 08:27
поделиться
  • 1
    Шейн, который также превратит числовые столбцы в характер. – Dirk Eddelbuettel 17 May 2010 в 19:38
  • 2
    @Dirk: Это правда, хотя неясно, есть ли здесь проблема. Ясно, что правильное создание вещей - это лучшее решение. Я не думаю, что easy автоматически преобразовывать типы данных в фрейм данных. Один из вариантов состоит в том, чтобы использовать выше, но затем использовать type.convert после того, как все было добавлено к character, а затем снова factors снова вернуться к character. – Shane 17 May 2010 в 19:56
  • 3
    Кажется, это отбрасывает имена строк. – piccolbo 22 July 2013 в 18:04
  • 4
    @piccolbo вы использовали bob[] <- в примере или bob <- ?; первый хранит data.frame; второй изменяет файл data.frame на список, отбрасывая имена розеток. Я обновлю ответ – David LeBauer 11 December 2014 в 22:51
  • 5
    Вариант, который преобразует столбцы факторов в символ с помощью анонимной функции: iris[] <- lapply(iris, function(x) if (is.factor(x)) as.character(x) else {x}) – Stefan F 5 July 2017 в 18:09

Или вы можете попробовать 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 вы можете делать все, что захотите, но по цене «пешеходный стиль - кодовое " ...

Итак, там ... =)

6
ответ дан aL3xa 18 August 2018 в 08:27
поделиться

Я обычно делаю эту функцию отдельно от всех моих проектов. Быстро и просто.

unfactorize <- function(df){
  for(i in which(sapply(df, class) == "factor")) df[[i]] = as.character(df[[i]])
  return(df)
}
11
ответ дан by0 18 August 2018 в 08:27
поделиться
  • 1
    Мне это нравится. Легко и легко понять. Для петель в R не хватает любви IMO – Tim_K 17 February 2016 в 22:30

Эта функция выполняет трюк

df <- stacomirtools::killfactor(df)
0
ответ дан Cedric 18 August 2018 в 08:27
поделиться

Другой способ - преобразовать его, используя apply

bob2 <- apply(bob,2,as.character)

И лучший (предыдущий - это «матрица» класса)

bob2 <- as.data.frame(as.matrix(bob),stringsAsFactors=F)
7
ответ дан George Dontas 18 August 2018 в 08:27
поделиться
  • 1
    Следуя комментарию @ Shane: чтобы получить data.frame, сделайте 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" 
3
ответ дан jangorecki 18 August 2018 в 08:27
поделиться
  • 1
    DT обольщает исправить исправление, предложенное Мареком: 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
19
ответ дан Kikapp 18 August 2018 в 08:27
поделиться

Для замены только факторов:

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

(помните, что это свежий пакет)

244
ответ дан Marek 18 August 2018 в 08:27
поделиться
  • 1
    Это очень полезный код, который можно быстро преобразовать в однострочный. – A5C1D2H2I1M1N2O1R2T1 7 July 2012 в 08:31
  • 2
    +1 Прекрасно сохраняет int при изменении этих надоедливых факторов – demongolem 25 September 2013 в 20:33
  • 3
    К сожалению, я не работаю для меня. Не знаю, почему. Наверное, потому что у меня есть имена? – Doctor Mohawk 18 July 2014 в 17:32
  • 4
    @mohawkjohn Не должно быть проблемой. Вы получили ошибку или результаты не так, как ожидали? – Marek 20 July 2014 в 22:51
  • 5
    Примечание: строка purrr возвращает список, а не data.frame! – RoyalTS 15 August 2016 в 15:49

Обновление: Вот пример того, что не работает. Я думал, что это произойдет, но я думаю, что параметр strAsAsFactors работает только с символьными строками - он оставляет только факторы.

Попробуйте следующее:

bob2 <- data.frame(bob, stringsAsFactors = FALSE)

Вообще говоря, у вас возникают проблемы с факторами, которые должны быть персонажами, есть где-то stringsAsFactors, чтобы помочь вам (включая глобальную настройку).

6
ответ дан Matt Parker 18 August 2018 в 08:27
поделиться
  • 1
    Это работает, если он устанавливает его при создании bob для начала (но не после факта). – Shane 17 May 2010 в 18:18
  • 2
    Правильно. Просто хотел быть ясным, что это не решает проблему, само по себе, но спасибо за то, что она ее предотвращает. – Matt Parker 17 May 2010 в 18:34

Глобальная опция

stringsAsFactors: параметр по умолчанию для аргументов data.frame и read.table.

может быть чем-то, что вы хотите установить на FALSE в ваших файлах запуска (например, ~ / .Rprofile). См. help(options).

36
ответ дан micstr 18 August 2018 в 08:27
поделиться
  • 1
    Спасибо за это! Такие вещи постоянно кусают меня, когда я набираю кривую обучения R! – Mike Dewar 17 May 2010 в 19:09
  • 2
    Проблема заключается в том, что когда вы выполняете свой код в среде, где отсутствует этот файл .Rprofile, вы получите ошибки! – wannymahoots 7 January 2015 в 12:20
  • 3
    Я обычно называю это в начале скриптов, а не в файле .Rprofile. – gregmacfarlane 8 May 2015 в 17:22

Если вам нужен новый фрейм данных bobc, где каждый вектор фактора в bobf преобразуется в вектор символов, попробуйте это:

bobc <- rapply(bobf, as.character, classes="factor", how="replace")

Если вы то вы хотите преобразовать его обратно, вы можете создать логический вектор, столбцы которого являются факторами, и использовать его для выборочного применения фактора

f <- sapply(bobf, class) == "factor"
bobc[,f] <- lapply(bobc[,f], factor)
17
ответ дан scentoni 18 August 2018 в 08:27
поделиться
  • 1
    +1 для выполнения только того, что было необходимо (т. Е. Не преобразования всего кадра данных в символ). Это решение является надежным для data.frame, который содержит смешанные типы. – Joshua Ulrich 1 August 2013 в 22:42
  • 2
    Этот пример должен быть в разделе «Примеры» для ссылки, например: stat.ethz.ch/R-manual/R-devel/library/base/html/rapply.html . Кто-нибудь знает, как просить об этом? – mpettis 2 August 2013 в 04:13
  • 3
    Если вы хотите получить кадр данных, просто оберните обращение в вызове data.frame (используя stringsAsFactors, установленный в аргумент FALSE) – Taylored Web Sites 4 April 2016 в 19:44

В начале вашего фрейма данных включите stringsAsFactors = FALSE, чтобы игнорировать все недоразумения.

4
ответ дан user 18 August 2018 в 08:27
поделиться

Это работает для меня - я, наконец, вычислил один лайнер

df <- as.data.frame(lapply(df,function (y) if(class(y)=="factor" ) as.character(y) else y),stringsAsFactors=F)
2
ответ дан user1617979 18 August 2018 в 08:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: