Как правильно преобразовать столбец символов в числовой? [Дубликат]

Большинство ответов здесь затрагивают этот вопрос в очень сухих технических терминах. Я хотел бы остановиться на этом в терминах, которые могут понять обычные люди.

Представьте, что вы пытаетесь нарезать пиццу. У вас есть роботизированный резак для пиццы, который может разрезать кусочки пиццы ровно пополам. Он может вдвое сократить целую пиццу, или он может сократить вдвое существующий кусочек, но в любом случае половина всегда точна.

У этого резца пиццы очень хорошие движения, и если вы начнете с целой пиццы, затем уменьшите вдвое и продолжайте вдвое уменьшать наименьший срез каждый раз, вы можете сделать половину 53 раза , прежде чем срез слишком мал для даже его высокоточных способностей. В этот момент вы уже не можете вдвое уменьшить этот тонкий срез, но должны либо включать, либо исключать его, как есть.

Теперь, как бы вы отделили все срезы таким образом, чтобы добавить один (0,1) или одну пятую (0,2) пиццы? На самом деле подумайте об этом и попробуйте разобраться. Вы даже можете попытаться использовать настоящую пиццу, если у вас есть мифическая пресса для резки пиццы под рукой. : -)


Большинство опытных программистов, конечно же, знают реальный ответ, который заключается в том, что нет возможности собрать кусок точной десятой или пятой пиццы используя эти срезы, независимо от того, насколько мелко вы их нарезаете. Вы можете сделать довольно хорошее приближение, и если вы добавите аппроксимацию 0,1 с аппроксимацией 0,2, вы получите довольно хорошее приближение 0,3, но это все равно именно это, приближение.

Для двойного -оценки (это точность, которая позволяет вам вдвое сократить вашу пиццу 53 раза), цифры сразу меньше и больше 0,1 - 0.09999999999999999167332731531132594682276248931884765625 и 0,1000000000000000055511151231257827021181583404541015625. Последнее немного ближе к 0,1, чем первое, поэтому числовой синтаксический анализатор, учитывая ввод 0,1, благоприятствует последнему.

(Разница между этими двумя числами - это «самый маленький срез», который мы должны решить либо включить, что вводит восходящее смещение, либо исключить, что приводит к смещению вниз. Техническим термином для этого наименьшего среза является ulp .)

В случай 0,2, числа все одинаковы, просто увеличиваются в 2 раза. Опять же, мы одобряем значение, которое немного выше 0,2.

Обратите внимание, что в обоих случаях приближения для 0,1 и 0.2 имеют небольшое смещение вверх. Если мы добавим достаточно этих предубеждений, они будут толкать число дальше и дальше от того, что мы хотим, а на самом деле, в случае 0,1 + 0,2, смещение достаточно велико, чтобы получившееся число больше не было самым близким числом до 0,3.

в частности, 0,1 + 0,2 действительно 0.1000000000000000055511151231257827021181583404541015625 + 0.200000000000000011102230246251565404236316680908203125 = 0.3000000000000000444089209850062616169452667236328125, тогда как число ближе к 0,3 фактически 0,299999999999999988897769753748434595763683319091796875.

П.С. Некоторые языки программирования также предоставляют резаки для пиццы, которые могут разделять фрагменты на точные десятки . Хотя такие резаки для пиццы необычны, если у вас есть доступ к одному, вы должны использовать его, когда важно получить ровно одну десятую или одну пятую части среза.

( Первоначально опубликовано на Quora.)

ч>

100
задан Henrik 21 February 2016 в 19:00
поделиться

10 ответов

Я хочу использовать R, а не предварительно обрабатывать данные, поскольку это облегчает пересмотр данных. Следуя предложению Шейна использовать gsub, я думаю, что это примерно так же аккуратно, как я могу:

x <- read.csv("file.csv",header=TRUE,colClasses="character")
col2cvt <- 15:41
x[,col2cvt] <- lapply(x[,col2cvt],function(x){as.numeric(gsub(",", "", x))})
14
ответ дан Rob Hyndman 26 August 2018 в 07:39
поделиться

Это не так сложно, попробуйте это: y & lt; - as.numeric (gsub (",", "", as.character (y))), и если это только один из столбцов, вы можете подмножить его с y $ 2, как показано y $ 2 & lt; - as.numeric (gsub (",", "", as.character (y $ 2)))

0
ответ дан Colonelxy 26 August 2018 в 07:39
поделиться

Очень удобный способ readr::read_delim -семейство. Взяв пример отсюда: Импортируя csv с несколькими разделителями в R , вы можете сделать это следующим образом:

txt <- 'OBJECTID,District_N,ZONE_CODE,COUNT,AREA,SUM
1,Bagamoyo,1,"136,227","8,514,187,500.000000000000000","352,678.813105723350000"
2,Bariadi,2,"88,350","5,521,875,000.000000000000000","526,307.288878142830000"
3,Chunya,3,"483,059","30,191,187,500.000000000000000","352,444.699742995200000"'

require(readr)
read_csv(txt) # = read_delim(txt, delim = ",")

. Это приводит к ожидаемому результату:

# A tibble: 3 × 6
  OBJECTID District_N ZONE_CODE  COUNT        AREA      SUM
     <int>      <chr>     <int>  <dbl>       <dbl>    <dbl>
1        1   Bagamoyo         1 136227  8514187500 352678.8
2        2    Bariadi         2  88350  5521875000 526307.3
3        3     Chunya         3 483059 30191187500 352444.7
50
ответ дан Community 26 August 2018 в 07:39
поделиться

Не знаете, как правильно интерпретировать read.csv, но вы можете использовать gsub для замены "," на "", а затем преобразовать строку в numeric с помощью as.numeric:

y <- c("1,200","20,000","100","12,111")
as.numeric(gsub(",", "", y))
# [1]  1200 20000 100 12111

Это было , также ранее упоминавшееся в R-Help (и в Q2 здесь ).

Кроме того, обрабатывать файл, например, с помощью sed в unix.

119
ответ дан Henrik 26 August 2018 в 07:39
поделиться

Используя функцию read_delim, которая является частью библиотеки readr, вы можете указать дополнительный параметр:

locale = locale(decimal_mark = ",")

read_delim("filetoread.csv", ';", locale = locale(decimal_mark = ","))

* Точка с запятой во второй строке означает, что read_delim будет считывать значения с разделителями с запятой csv.

Это поможет прочитать все числа с запятой как правильные числа.

С уважением

Mateusz Kania

-1
ответ дан Mateusz Kania 26 August 2018 в 07:39
поделиться

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

Библиотека / пакет readr имеет некоторые полезные функции. Один из них - хороший способ интерпретировать «грязные» столбцы, такие как.

library(readr)
read_csv("numbers\n800\n\"1,800\"\n\"3500\"\n6.5",
          col_types = list(col_numeric())
        )

Это дает

Источник: локальный фрейм данных [4 x 1]

  numbers
    (dbl)
1   800.0
2  1800.0
3  3500.0
4     6.5

Важным моментом при чтении файлов является либо предварительная обработка, как комментарий выше относительно sed, либо вы должны обрабатывать во время чтения. Часто, если вы пытаетесь исправить ситуацию после факта, есть некоторые опасные предположения, которые трудно найти. (Вот почему плоские файлы так злы в первую очередь.)

Например, если бы я не помечен col_types, я бы получил следующее:

> read_csv("numbers\n800\n\"1,800\"\n\"3500\"\n6.5")
Source: local data frame [4 x 1]

  numbers
    (chr)
1     800
2   1,800
3    3500
4     6.5

(Обратите внимание, что теперь это chr (character) вместо numeric.)

Или, что более опасно, если бы оно было достаточно длинным, и большинство ранних элементов не содержало запятые:

> set.seed(1)
> tmp <- as.character(sample(c(1:10), 100, replace=TRUE))
> tmp <- c(tmp, "1,003")
> tmp <- paste(tmp, collapse="\"\n\"")

(так, что последние несколько элементов выглядят так:)

\"5\"\n\"9\"\n\"7\"\n\"1,003"

Тогда вы найдете проблемы с чтением этой запятой вообще!

> tail(read_csv(tmp))
Source: local data frame [6 x 1]

     3"
  (dbl)
1 8.000
2 5.000
3 5.000
4 9.000
5 7.000
6 1.003
Warning message:
1 problems parsing literal data. See problems(...) for more details. 
11
ответ дан Mike Williamson 26 August 2018 в 07:39
поделиться

Другое решение:

 y <- c("1,200","20,000","100","12,111") 

 as.numeric(unlist(lapply( strsplit(y,","),paste, collapse="")))

Это будет значительно медленнее, чем gsub.

0
ответ дан oers 26 August 2018 в 07:39
поделиться

решение dplyr с использованием mutate_each и труб

говорит, что у вас есть следующее:

> dft
Source: local data frame [11 x 5]

   Bureau.Name Account.Code   X2014   X2015   X2016
1       Senate          110 158,000 211,000 186,000
2       Senate          115       0       0       0
3       Senate          123  15,000  71,000  21,000
4       Senate          126   6,000  14,000   8,000
5       Senate          127 110,000 234,000 134,000
6       Senate          128 120,000 159,000 134,000
7       Senate          129       0       0       0
8       Senate          130 368,000 465,000 441,000
9       Senate          132       0       0       0
10      Senate          140       0       0       0
11      Senate          140       0       0       0

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

dft %>%
    mutate_each(funs(as.character(.)), X2014:X2016) %>%
    mutate_each(funs(gsub(",", "", .)), X2014:X2016) %>%
    mutate_each(funs(as.numeric(.)), X2014:X2016)

mutate_each применяет функцию (ы) внутри funs к указанным столбцам

I последовательно выполнял одну функцию за раз (если вы используете несколько функций внутри funs, тогда вы создаете дополнительные ненужные столбцы)

4
ответ дан Paul Paczuski 26 August 2018 в 07:39
поделиться

Я думаю, что предварительная обработка - это путь. Вы можете использовать Notepad ++ , у которого есть опция замены регулярного выражения.

Например, если ваш файл был таким:

"1,234","123","1,234"
"234","123","1,234"
123,456,789

Тогда вы могли бы используйте регулярное выражение "([0-9]+),([0-9]+)" и замените его на \1\2

1234,"123",1234
"234","123",1234
123,456,789

. Затем вы можете использовать x <- read.csv(file="x.csv",header=FALSE) для чтения файла.

2
ответ дан Sathya 26 August 2018 в 07:39
поделиться

Если номер разделен символом "." и десятичные знаки «,» (1.200.000,00) при вызове gsub вы должны set fixed=TRUE as.numeric(gsub(".","",y,fixed=TRUE))

3
ответ дан StuartLC 26 August 2018 в 07:39
поделиться
Другие вопросы по тегам:

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