R: есть ли способ связать нечисловые столбцы

library(Rmpfr)
mynumber <- new("mpfr", .Data = list(new("mpfr1", prec = 50L, exp = c(1045L, 
0L), sign = 1L, d = c(151748608L, -358118319L)), new("mpfr1", 
    prec = 50L, exp = c(20L, 0L), sign = 1L, d = c(-1114947584L, 
    -1905679017L)), new("mpfr1", prec = 50L, exp = c(-55L, -1L
), sign = 1L, d = c(-1449918464L, -906197701L)), new("mpfr1", 
    prec = 50L, exp = c(221L, 0L), sign = 1L, d = c(819707904L, 
    -1329031570L))))

mynumber — это объект класса mpfr с 4 числами в нем. Я хочу cbind mynumber со столбцом из 0, т.е.

> cbind(rep(0, 4), mynumber)
       mynumber
[1,] 0 ?       
[2,] 0 ?       
[3,] 0 ?       
[4,] 0 ?  

Это дает мне ???? во втором столбце, поэтому я попытался сначала изменить mynumber на класс numeric

mydata <- cbind(rep(0, 4), sapply(mynumber, asNumeric))
> mydata
     [,1]         [,2]
[1,]    0          Inf
[2,]    0 5.833223e+05
[3,]    0 2.189941e-17
[4,]    0 2.327185e+66

Однако, поскольку первое число в mynumber действительно большое, использование asNumeric вместо этого изменило его на Inf.

Изменить: моя конечная цель - запустить:

mydata <- cbind(rep(0, 4), sapply(mynumber, asNumeric))
> mydata/rowSums(mydata)
     [,1] [,2]
[1,]    0  NaN
[2,]    0    1
[3,]    0    1
[4,]    0    1

и не распечатывать NaN.


person Adrian    schedule 29.02.2020    source источник
comment
mynumber результат моего вызова функции mpfr из Rmpfr. Есть ли дополнительная информация о пакетах, которую я должен предоставить?   -  person Adrian    schedule 29.02.2020


Ответы (3)


Один из вариантов - обернуть list, а затем создать объект tibble/data.frame, поскольку cbind преобразуется в matrix, а matrix может содержать только один класс.

library(tibble)
tibble(col1 = 0, col2 = list(mynumber))
# A tibble: 1 x 2
#   col1 col2  
#  <dbl> <list>
#1     0 <mpfr>

cbind даже для классов character и numeric возвращает character для всех столбцов, и это не лучший вариант, когда vector для привязки относятся к другому классу.

cbind(letters[1:4], 1:4)

Проверяя methods на cbind после загрузки пакета

methods('cbind')
#[1] cbind,ANY-method     cbind,Mnumber-method cbind.bigq*          cbind.bigz*         
#[5] cbind.data.frame     cbind.grouped_df*    cbind.ts*       

Таким образом, если он использовал правильные методы cbind для Mnumber, он не должен был выдавать Inf

cbind(rep(0,4),  mynumber)
#'mpfrMatrix' of dim(.) =  (4, 2) of precision  50 .. 53  bits 
#     [,1] [,2]                   
#[1,]   0. 3.4556867084990952e+314
#[2,]   0.      583322.33392099757
#[3,]   0.  2.1899410233914937e-17
#[4,]   0.  2.3271850367397449e+66

Или используйте переработку стоимости

cbind(0,  mynumber)
#'mpfrMatrix' of dim(.) =  (4, 2) of precision  50 .. 53  bits 
#     [,1] [,2]                   
#[1,]   0. 3.4556867084990952e+314
#[2,]   0.      583322.33392099757
#[3,]   0.  2.1899410233914937e-17
#[4,]   0.  2.3271850367397449e+66

Кроме того, если мы проверим замаскированные функции, когда мы загружаем пакет, он говорит

Следующие объекты маскируются от ‘package:base’:

cсвязь, pmax, pmin, rсвязь

Используя cbind из base, можно воспроизвести ?. Возможно, что для ОП cbind от base

base::cbind(0, mynumber)
#       mynumber
#[1,] 0 ?       
#[2,] 0 ?       
#[3,] 0 ?       
#[4,] 0 ?       

Если cbind из Rmpfr замаскировано, используйте ::

mydata <- Rmpfr::cbind(0, mynumber)
mydata
#'mpfrMatrix' of dim(.) =  (4, 2) of precision  50 .. 53  bits 
#     [,1] [,2]                   
#[1,]   0. 3.4556867084990952e+314
#[2,]   0.      583322.33392099757
#[3,]   0.  2.1899410233914937e-17
#[4,]   0.  2.3271850367397449e+66




mydata/rowSums(mydata)
#'mpfrMatrix' of dim(.) =  (4, 2) of precision  53   bits 
#     [,1] [,2]              
#[1,]   0. 1.0000000000000000
#[2,]   0. 1.0000000000000000
#[3,]   0. 1.0000000000000000
#[4,]   0. 1.0000000000000000
person akrun    schedule 29.02.2020
comment
Спасибо. У меня есть дополнительный вопрос, предположим, у меня есть mydata <- cbind(rep(0, 4), sapply(mynumber, asNumeric)). И когда я звоню mydata/rowSums(mydata), мне дают NaN. Есть ли способ использовать tibble, чтобы обойти это? Я отредактировал свой исходный вопрос. - person Adrian; 29.02.2020
comment
Тогда пойдем с mydata <- cbind(seq(1, 4, 1), sapply(mynumber, asNumeric)). - person Adrian; 29.02.2020
comment
Спасибо. Как убедиться, что метод cbind используется для Mnumber? - person Adrian; 29.02.2020

Интересно, что-то не так с вашим созданным объектом. Когда я изменил его, чтобы каждое поле exp имело только одно значение, я получил желаемый результат:

library(Rmpfr)

x <- new("mpfr", .Data = list(new("mpfr1", prec = 50L, exp = 1045L, 
    sign = 1L, d = c(151748608L, -358118319L)), new("mpfr1", 
    prec = 50L, exp = 20L, sign = 1L, d = c(-1114947584L, -1905679017L
    )), new("mpfr1", prec = 50L, exp = -55L, sign = 1L, d = c(-1449918464L, 
-906197701L)), new("mpfr1", prec = 50L, exp = 221L, sign = 1L, 
    d = c(819707904L, -1329031570L))))

cbind(c(0, 0, 0, 0), x)
#> 'mpfrMatrix' of dim(.) =  (4, 2) of precision  50 .. 53  bits 
#>      [,1] [,2]                   
#> [1,]   0. 3.4556867084990952e+314
#> [2,]   0.      583322.33392099757
#> [3,]   0.  2.1899410233914937e-17
#> [4,]   0.  2.3271850367397449e+66

Создана 29 февраля 2020 г. в пакете reprex (v0.3.0)

person Allan Cameron    schedule 29.02.2020
comment
Когда я попытался запустить x <- new(....), я получил следующую ошибку: Error in validObject(.Object) : invalid class “mpfr1” object: invalid 'exp' slot for 64-bit gmp.numbbits: must have length 2. Не знаете, что это значит? - person Adrian; 29.02.2020
comment
@ Адриан Я предполагаю, что это потому, что у меня 32-битная архитектура, а у тебя 64-битная. Я подозреваю, что это проблема с версией cbind, которая называется, как говорит @akrun. - person Allan Cameron; 29.02.2020

person    schedule
comment
Спасибо. Я получил следующую ошибку: Error in base::"%*%"(x, y) : requires numeric/complex matrix/vector arguments. Я полагаю, что использую оператор %*% из другого пакета? - person Adrian; 29.02.2020
comment
@ Адриан Стрэндж. Я только что загрузил Rmpfr, который предоставляет этот оператор. - person Stéphane Laurent; 29.02.2020