Как преобразовать dataframe в класс S4 в R? [Дубликат]

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

Мой метод является общим, в котором вы можете добавить дополнительные разделители посредством запятой, разделяющей переменную delimiters= доказательство этого.

Рабочий код:

import pandas as pd
import re


df = pd.DataFrame({'$a':[1,2], '$b': [3,4],'$c':[5,6], '$d': [7,8], '$e': [9,10]})

delimiters = '$'
matchPattern = '|'.join(map(re.escape, delimiters))
df.columns = [re.split(matchPattern, i)[1] for i in df.columns ]

Выход:

>>> df
   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

>>> df
   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10
8
задан Karsten W. 11 May 2013 в 23:59
поделиться

2 ответа

Вот ваш класс, с интерпретацией «колонки» его определения, а не с строкой; это будет важно для производительности; также дате ссылки

setClass("person", representation(name="character", age="numeric"))
pers <- new("person", name=c("John", "Tom"), age=c(20, 30))
date <- as.POSIXct(c('2013-01-01', '2013-01-02'))

Некоторые эксперименты, включая просмотр methods(class="POSIXct") и обратное внимание к сообщениям об ошибках, привели меня к реализации as.data.frame.person и format.person (последний используется для отображения в данных .frame) как

as.data.frame.person <-
    function(x, row.names=NULL, optional=FALSE, ...)
{
    if (is.null(row.names))
        row.names <- x@name
    value <- list(x)
    attr(value, "row.names") <- row.names
    class(value) <- "data.frame"
    value
}

format.person <- function(x, ...) paste0(x@name, ", ", x@age)

Это получает мои объекты в файле data.frame:

> lst <- list(id=1:2, date=date, pers=pers)
> as.data.frame(lst)
     id       date     pers
John  1 2013-01-01 John, 20
Tom   2 2013-01-02  Tom, 30

Если я хочу подмножество, тогда мне нужно

setMethod("[", "person", function(x, i, j, ..., drop=TRUE) {
    initialize(x, name=x@name[i], age=x@age[i])
})

Я не уверен, какие другие методы могут потребоваться по мере того, как встречаются больше операций data.frame, нет «интерфейса data.frame».

Использование векторизованного класса в data.table кажется для использования метода длины для построения.

> library(data.table)
> data.table(id=1:2, pers=pers)
Error in data.table(id = 1:2, pers = pers) : 
  problem recycling column 2, try a simpler type
> setMethod(length, "person", function(x) length(x@name))
[1] "length"
> data.table(id=1:2, pers=pers)
   id     pers
1:  1 John, 20
2:  2  Tom, 30

Возможно, есть интерфейс data.table?

7
ответ дан Martin Morgan 26 August 2018 в 02:19
поделиться

Судя по этой теме в списке рассылки:

http://tolstoy.newcastle.edu.au/R/e2/devel/06/11/1013.html

... Джон Чамберс думал об этом в 2006 году. И все же мы не можем помещать объекты S4 в столбцы кадров данных. Мы также не можем помещать сложные классы S3 в столбцы кадров данных.

Существуют и другие структуры табличных данных, которые могут это сделать - data.table возможно:

require(data.table)
setClass("geezer", representation(name="character", age="numeric"))
tom=new("geezer",name="Tom",age=20)
dick=new("geezer",name="Dick",age=23)
harry=new("geezer",name="Harry",age=25)
gt = data.table(geezers=c(tom,dick,harry),weapons=c("Gun","Gun","Knife"))
gt
    geezers weapons
1: <geezer>     Gun
2: <geezer>     Gun
3: <geezer>   Knife

Семантика data.table немного отличается от data.frame и не ожидает, что сможет подключить data.table к любому коду, использующему data.frame, и ожидать, что он будет работать (например, я подозреваю lm и glm пошатнутся). Но, кажется, авторы data.table допускают составные классы в столбцах ...

2
ответ дан Spacedman 26 August 2018 в 02:19
поделиться
Другие вопросы по тегам:

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