R: разделение числовой строки

Я пытаюсь разбить числовую строку из 40 цифр (т.е. разделить 123456789123456789123456789 на 1 2 3 4 и т. д.)

К сожалению, strsplit не работает, так как для этого требуются символы, а преобразование строки с использованием as.character не работает, поскольку она очень длинная, а R автоматически отсекает десятичные знаки для длинных цифр (максимум 22 десятичных знака). Таким образом, я получаю "1.2345e+35" в качестве строки символов вместо полной цифры.

Есть ли числовой вариант strsplit или решение проблемы десятичного отсечения? Кажется, я не могу найти ответ на stackoverflow, но извиняюсь, если на этот вопрос уже был дан ответ. Заранее спасибо!


person rvrvrv    schedule 03.06.2012    source источник
comment
с какого формата вы начинаете? символ или число?   -  person Ben Bolker    schedule 03.06.2012
comment
это число, поэтому strsplit выдает ошибку   -  person rvrvrv    schedule 03.06.2012
comment
но если вы имеете дело с очень большим числовым значением, R, вероятно, уже потерял точность. Максимальное значение options("digits") равно 22 ; Я не уверен в максимальной точности, которую R может удерживать в переменной numeric, но я думаю, что ваше значение больше этого. Возможно, вы захотите просмотреть некоторые из ответов SO на ваши варианты арифметики произвольной точности (в основном с использованием интерфейсов для инструментов, отличных от R, таких как bc): например, stackoverflow.com/questions/8175965/   -  person Ben Bolker    schedule 03.06.2012
comment
Например: xc <- "123456789123456789123456789"; x <- as.numeric(xc); dump("x","")   -  person Ben Bolker    schedule 03.06.2012
comment
@BenBolker: с/вероятно/определенно. Числовой класс R имеет двойную точность, что дает вам только ~ 16 цифр. Все, что после этого, является ошибкой округления. В этом случае действительно поможет воспроизводимый пример... ОП: как это число создается в R?   -  person Joshua Ulrich    schedule 03.06.2012
comment
... Я только что проверил пакет int64, и даже беззнаковые 64-битные целые числа дают вам только 20 цифр ... library(int64); as.character(numeric_limits("uint64"))   -  person Ben Bolker    schedule 03.06.2012
comment
См. также: rwiki.sciviews.org/   -  person Ben Bolker    schedule 03.06.2012
comment
Если вы можете преобразовать в символ, вручную поместив число в кавычки, это сработает? a1 ‹- '1234567891234567891234567891234567891234'; a2 ‹- strsplit(a1, ) ; a3 ‹- удалить из списка (a2) ; a4 ‹- as.vector(as.numeric(a3)) ;   -  person Mark Miller    schedule 04.06.2012
comment
Я думал, что options("digits") указывает только количество десятичных знаков, которое показывает R, а не число, которое он поддерживает и использует для вычислений? Невозможно перейти от числового к символьному, поскольку R, по-видимому, использует 1.2345e+35 вместо целого числа, и, таким образом, это то, что возвращается как символ. Данные извлекаются из базы данных MySQL, поэтому я вернулся туда и изменил категорию с VARCHAR на CHAR (но, к сожалению, пришлось переделать все управление данными). Таким образом, моя проблема решена, но преобразование числа в символ с использованием больших чисел все еще остается проблемой.   -  person rvrvrv    schedule 04.06.2012
comment
Вы правы, что options('digits') управляет только печатью. R выполняет все вычисления с двойной точностью, которая (как я уже говорил в предыдущем комментарии) ограничена примерно 16-ю цифрами точности. Столбец VARCHAR не является проблемой, поскольку ваша БД хранит значение в виде строки. Проблема в том, что любой метод, который вы использовали для извлечения данных в R, преобразовывал это поле в числовое.   -  person Joshua Ulrich    schedule 04.06.2012


Ответы (3)


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

a1 <- read.table("c:/users/Mark W Miller/simple R programs/long_number.txt", colClasses = 'character')

# a1 <- c('1234567891234567891234567891234567891234') ;

a1 <- as.character(a1) ;
a2 <- strsplit(a1, "") ;
a3 <- unlist(a2) ;
a4 <- as.vector(as.numeric(a3)) ;
a4
# [1] 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4

РЕДАКТИРОВАТЬ

Я понимаю, что могу не понять вопроса, и мой ответ, вероятно, довольно глупый. Тем не менее, если у вас есть полный набор данных действительно длинных чисел, вы можете разделить их все с помощью приведенного ниже кода. Обратите внимание, что в файле «three_long_numbers.txt» нет кавычек, а данные начинаются как числовые:

a1 <- read.table("c:/users/Mark W Miller/simple R programs/three_long_numbers.txt", colClasses = 'character')
a1

#      V1                                        
# [1,] "1234567891234567891234567891234567891234"
# [2,] "1888678912345678912345678912345678912388"
# [3,] "1234999891234567891234567891234567891239"

# a1 <- matrix(c(
# "1234567891234567891234567891234567891234",
# "1888678912345678912345678912345678912388",
# "1234999891234567891234567891234567891239"), nrow=3, byrow=T)

a1 <- as.matrix(a1) ;
a2 <- strsplit(a1, "") ;
a3 <- unlist(a2) ;
a3 <- as.numeric(a3) ;
a4 <- matrix(a3, nrow=dim(a1)[1], byrow=T)
a4
person Mark Miller    schedule 03.06.2012

Вы можете просто сделать это, чтобы разбить числовой вектор:

s <- "123456789123456789123456789"
as.numeric(strsplit(s,"")[[1]])

# [1] 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9

или если вы хотите, чтобы они были разделены как вектор символов:

strsplit(s,"")[[1]]

# [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "1" "2" "3" "4" "5" "6" "7" "8" 
# "9" "1" "2" "3" "4" "5" "6"
# [25] "7" "8" "9"
person 989    schedule 18.07.2016

Вот еще один подход, который кажется более прямолинейным, чем мой ответ год назад:

Разделить один вектор:

a1 <- c('1234567891234567891234567891234567891234')
a2 <- read.fwf(textConnection(a1), widths=rep(1, nchar(a1)), colClasses = 'numeric', header=FALSE)
a2
  V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40
1  1  2  3  4  5  6  7  8  9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4

Прочитайте файл, содержащий следующие три длинных числа одинаковой длины:

# 1234567891234567891234567891234567891234
# 1888678912345678912345678912345678912388
# 1234999891234567891234567891234567891239

a1 <- read.table("c:/users/mmiller21/simple R programs/three_long_numbers.txt", colClasses = 'character', header = FALSE)
a2 <- read.fwf("c:/users/mmiller21/simple R programs/three_long_numbers.txt", widths=rep(1, max(nchar(a1$V1))), colClasses = 'numeric', header=FALSE)
a2

  V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40
1  1  2  3  4  5  6  7  8  9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4
2  1  8  8  8  6  7  8  9  1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   8   8
3  1  2  3  4  9  9  9  8  9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   9

Считайте файл, содержащий следующие три длинных числа неравной длины:

# 1234567891234567891234567891234567891234
# 188867891234567891234567891234567891238
# 12349998912345678912345678912345678912

a1 <- read.table("c:/users/mmiller21/simple R programs/three_long_numbersb.txt", colClasses = 'character', header = FALSE)
a2 <- read.fwf("c:/users/mmiller21/simple R programs/three_long_numbersb.txt", widths=rep(1, max(nchar(a1$V1))), colClasses = 'numeric', header=FALSE)
a2

  V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40
1  1  2  3  4  5  6  7  8  9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4
2  1  8  8  8  6  7  8  9  1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   8  NA
3  1  2  3  4  9  9  9  8  9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2  NA  NA

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

# -10 1234567891234567891234567891234567891234 -100
# -20 1888678912345678912345678912345678912388 -200
# -30 1234999891234567891234567891234567891239 -300

a1 <- read.table("c:/users/mark w miller/simple R programs/three_long_numbers_Oct25_2013.txt", colClasses = c('numeric', 'character', 'numeric'), header = FALSE)
a2 <- read.fwf(textConnection(a1$V2), widths=rep(1, nchar(a1$V2)[1]), colClasses = 'numeric', header=FALSE)
  V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40
1  1  2  3  4  5  6  7  8  9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4
2  1  8  8  8  6  7  8  9  1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   8   8
3  1  2  3  4  9  9  9  8  9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3   9
person Mark Miller    schedule 23.07.2013