Переопределение метода подмножества в R для определенного класса мешает работе других объектов

Я работаю с R и создал новый метод subset для объектов класса new_object. Вот моя функция:

setGeneric('subset', function(x, i) standardGeneric('subset'))
setMethod('subset', 'new_object', function(x, i) { 
    # ... my code ...
    # subset new_object

})

Это отлично работает для new_object. Однако, похоже, это мешает работе подмножества других объектов, например объектов seurat. Я получаю сообщение об ошибке, когда пытаюсь подмножество объекта seurat после загрузки нового метода подмножества.

The inheritance method for the 'subset' function with the 'Seurat' tag could not be found.

Я бы хотел, чтобы метод subset работал как обычно для всех остальных типов объектов, кроме new_object, для которого я хочу использовать свой новый метод subset.

Как я могу определить новый метод подмножества для определенного класса, не затрагивая другие объекты в R?

Возможно это: stackoverflow.com/a/12712646/1412059

Roland 29.05.2024 11:10
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В чистом, только что открытом R запустите subset без фигурных скобок, чтобы увидеть, что это за объект.

> subset
function (x, ...) 
UseMethod("subset")
<bytecode: 0x0000019b6e422730>
<environment: namespace:base>

Итак, это универсальная функция S3 с аргументами x, ... и находится в пакете base. Таким образом, когда вы вызываете setGeneric('subset', function(x, i) standardGeneric('subset')), вы создаете новую универсальную функцию с аргументами x, i, которая отличается от существующих аргументов x, ... для subset, определенных в пакете base.
Решение состоит в том, чтобы вызвать setGeneric("subset"), чтобы существующая функция (subset в пакете base) стала универсальной функцией S4.

> setGeneric("subset")
> setClass("new_object")
> setMethod("subset", "new_object", function(x, i, ...) { 
    # ... your code here ...
    # subset new_object
    # below is an example
    print(x)
})

> subset
standardGeneric for "subset" defined from package "base"

function (x, ...) 
standardGeneric("subset")
<environment: 0x000001f4839ab3b8>
Methods may be defined for arguments: x
Use  showMethods(subset)  for currently available ones.

> showMethods("subset", includeDefs = TRUE)
Function: subset (package base)
x = "ANY"
function (x, ...) 
UseMethod("subset")


x = "new_object"
function (x, ...) 
{
    .local <- function (x, i, ...) 
    {
        print(x)
    }
    .local(x, ...)
}

Как вы можете видеть из showMethods("subset", includeDefs = TRUE), когда вы вызываете этот S4 subset с помощью x класса new_object, он будет отправлен в ваши пользовательские методы. При вызове любого другого класса он будет использовать существующий механизм диспетчеризации S3 (т. е. UseMethod).

Примечание. Хорошей практикой является использование в вашем методе всех аргументов универсального метода, включая… если в данном случае универсальный аргумент есть, setMethod("subset", "new_object", function(x, i, ...) {# your code here ...} (большое спасибо @JDL за то, что познакомил меня с этим моментом).

Спасибо за ответ, он очень хорошо отвечает на мой вопрос. На самом деле я не очень хорошо знаком с объектами в языке R, поскольку они сильно отличаются от таких языков, как Python. Не могли бы вы объяснить здесь назначение setGeneric() и setMethod()? Похоже, что setGeneric определяет функцию, а setMethod определяет реализацию этой функции?

zhang 29.05.2024 14:00

@zhang Предлагаю вам прочитать главу Advanced R, написанную Хэдли Уикхэмом по S4: adv-r.had.co.nz/S4.html

SamR 29.05.2024 23:25

@zhang Можете ли вы сделать это вопросом вместо комментария? Я постараюсь ответить на него. Раздел комментариев довольно мал для таких вещей. Кроме того, ссылка, предоставленная SamR, предназначена для старой версии Advanced R, новая версия: https://adv-r.hadley.nz/s4.html

Hieu Nguyen 31.05.2024 18:32

кстати, я бы рекомендовал добавить "..." в качестве аргумента вашего метода, даже если он вам не нужен, потому что это аргумент общего метода. в руководстве по написанию расширений R объясняется, почему рекомендуется это делать.

JDL 01.06.2024 20:46

@JDL большое спасибо за ваш вклад. Первоначально я видел, что WRE ограничивает обсуждение S3, но, подумав некоторое время, я думаю, что его совет применим и к S4.

Hieu Nguyen 17.06.2024 16:28

Другие вопросы по теме