Help with first S3-class

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Help with first S3-class

Martin Møller Skarbiniks Pedersen
Hi,

  I am trying to understand S3 classes. I have read several tutorials about
the topics but I am still a bit confused. I guess it is because it is
so different from
Java OOP.

  I have pasted my attempt at creating a bank-account class below and
my problems are:

1. What should be added some plot.default() calls the account$plot() method ?
2. What should the account$plot() be implemented to show some kind of plot ?
3. How can one function inside "me"-list called another function. Eg.
How can account$plot() call account$pastSaldo() ?

Here are my code. Feel free to comment on any aspect of the code.
ps. I hope I have manage to strip HTML.

Regards
Martin



account <- function(owner = NULL) {
    thisEnv <- environment()

    pastSaldo <- vector()
    saldo <- 0
    owner <- owner

    me <- list(
    thisEnv = thisEnv,

         getEnv = function() { return(get("thisEnv", thisEnv)) },

         balance = function() { return(get("saldo", thisEnv)) },

        deposit = function(value) {
            assign("pastSaldo", append(pastSaldo, saldo), thisEnv)
            assign("saldo", saldo + value, thisEnv)
        },

        withdraw = function(value) {
           assign("pastSaldo", append(pastSaldo, saldo), thisEnv)
           assign("saldo", saldo - value, thisEnv)
        },

       pastSaldo = function() {
          return(pastSaldo)
      },

      plot = function() {
         plot.new()
         lines(list(y = pastSaldo, x = seq_along(pastSaldo)))
       }
    )
    assign('this', me, envir = thisEnv)

    class(me) <- append(class(me), "account")
    return(me)
}

FirstAccount <- account("Martin")
FirstAccount$deposit(100)
FirstAccount$withdraw(50)
FirstAccount$deposit(200)
FirstAccount$balance()
FirstAccount$pastSaldo()

FirstAccount$plot()

plot(FirstAccount)                            # fails
plot.account(FirstAccount)               # fails

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Help with first S3-class

Duncan Murdoch-2
On 02/01/2018 6:38 PM, Martin Møller Skarbiniks Pedersen wrote:
> Hi,
>
>    I am trying to understand S3 classes. I have read several tutorials about
> the topics but I am still a bit confused. I guess it is because it is
> so different from
> Java OOP.

What you do below isn't S3.  S3 is a system where the classes are
secondary to the generic functions.  Methods "belong" to generics, they
don't belong to classes.  As far as I can see, you hardly make use of S3
methods and generics at all.

For the style you're using, the R6 or R.oo packages might be more suitable.

>
>    I have pasted my attempt at creating a bank-account class below and
> my problems are:
>
> 1. What should be added some plot.default() calls the account$plot() method ?

No, you need to define a function called "plot.account" whose signature
is compatible with plot, i.e. arguments (x, y, ...), possibly with extra
parameters as well.  It should do the plotting.

> 2. What should the account$plot() be implemented to show some kind of plot ?

The plot.account function could call account$plot(); it can do whatever
you want to plot the object.

> 3. How can one function inside "me"-list called another function. Eg.
> How can account$plot() call account$pastSaldo() ?

There's no particular support for having them see each other the way
you've defined them.  A better way to define them would be as local
functions within the account body; then they'd be able to see each other
without any prefix.

Duncan Murdoch

>
> Here are my code. Feel free to comment on any aspect of the code.
> ps. I hope I have manage to strip HTML.
>
> Regards
> Martin
>
>
>
> account <- function(owner = NULL) {
>      thisEnv <- environment()
>
>      pastSaldo <- vector()
>      saldo <- 0
>      owner <- owner
>
>      me <- list(
>      thisEnv = thisEnv,
>
>           getEnv = function() { return(get("thisEnv", thisEnv)) },
>
>           balance = function() { return(get("saldo", thisEnv)) },
>
>          deposit = function(value) {
>              assign("pastSaldo", append(pastSaldo, saldo), thisEnv)
>              assign("saldo", saldo + value, thisEnv)
>          },
>
>          withdraw = function(value) {
>             assign("pastSaldo", append(pastSaldo, saldo), thisEnv)
>             assign("saldo", saldo - value, thisEnv)
>          },
>
>         pastSaldo = function() {
>            return(pastSaldo)
>        },
>
>        plot = function() {
>           plot.new()
>           lines(list(y = pastSaldo, x = seq_along(pastSaldo)))
>         }
>      )
>      assign('this', me, envir = thisEnv)
>
>      class(me) <- append(class(me), "account")
>      return(me)
> }
>
> FirstAccount <- account("Martin")
> FirstAccount$deposit(100)
> FirstAccount$withdraw(50)
> FirstAccount$deposit(200)
> FirstAccount$balance()
> FirstAccount$pastSaldo()
>
> FirstAccount$plot()
>
> plot(FirstAccount)                            # fails
> plot.account(FirstAccount)               # fails
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Help with first S3-class

Martin Møller Skarbiniks Pedersen
On 3 January 2018 at 00:52, Duncan Murdoch <[hidden email]> wrote:

> On 02/01/2018 6:38 PM, Martin Møller Skarbiniks Pedersen wrote:
>>
>> Hi,
>>
>>    I am trying to understand S3 classes. I have read several tutorials
>> about
>> the topics but I am still a bit confused. I guess it is because it is
>> so different from
>> Java OOP.
>
>
> What you do below isn't S3.  S3 is a system where the classes are secondary
> to the generic functions.  Methods "belong" to generics, they don't belong
> to classes.  As far as I can see, you hardly make use of S3 methods and
> generics at all.
>
> For the style you're using, the R6 or R.oo packages might be more suitable.

OK. Thanks, I will rewrite the code.

I read the guide at https://www.programiz.com/r-programming/S3-class
to make the code.
And used the part under: 1.3.2. Local Environment Approach

There is a picture of Wickham and it is sponsored by Datacamp so I was
thinking it was a good place for a guide ?!

Regards
Martin

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Help with first S3-class

Martin Møller Skarbiniks Pedersen
In reply to this post by Duncan Murdoch-2
On 3 January 2018 at 00:52, Duncan Murdoch <[hidden email]> wrote:

> On 02/01/2018 6:38 PM, Martin Møller Skarbiniks Pedersen wrote:
>>
>> Hi,
>>
>>    I am trying to understand S3 classes. I have read several tutorials
>> about
>> the topics but I am still a bit confused. I guess it is because it is
>> so different from
>> Java OOP.
>
>
> What you do below isn't S3.  S3 is a system where the classes are secondary
> to the generic functions.  Methods "belong" to generics, they don't belong
> to classes.  As far as I can see, you hardly make use of S3 methods and
> generics at all.

Here is my second attempt making a S3-class.
But something is wrong with the deposit.account() ? Thanks for any help.

I expect this output:

[1] 0
Martin
Saldo is:  100

but I get this:

[1] 100
Martin
Saldo is:  0

Regards
Martin

account <- function(owner = NULL) {
if (is.null(owner)) stop("Owner can't be NULL")
value <- list(owner = owner, saldo = 0)
attr(value, "class") <- "account"
value
}

balance <- function(obj) { UseMethod("balance") }

balance.account <- function(obj) {
obj$saldo
}

deposit <- function(obj, amount) { UseMethod("deposit") }

deposit.account <- function(obj, amount) {
obj$saldo <- obj$saldo + amount
}

print.account <- function(obj) {
cat(obj$owner, "\n")
cat("Saldo is: ", obj$saldo, "\n")
}

A1 <- account("Martin")
deposit(A1, 100)
balance(A1)
print(A1)

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Help with first S3-class

Martin Møller Skarbiniks Pedersen
Some mistake:

> I expect this output:

[1] 100
Martin
Saldo is: 100

but I get

[1] 0
Martn
Saldo is: 0

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Help with first S3-class

Jeff Newmiller
Function arguments are not pass-by-reference... they are pass-by-value. You need to return the altered object to the caller when you are done messing with it.

Note that R is a data processing language... your example will not scale to real world use cases because you make no use of vectorization to handle multiple accounts. It is better to focus on the functional aspect of computing and let the objects carry the results until you have a chance to summarize or plot them.  Study the "lm" function and associated print and plot methods.
--
Sent from my phone. Please excuse my brevity.

On January 2, 2018 4:37:01 PM PST, "Martin Møller Skarbiniks Pedersen" <[hidden email]> wrote:

>Some mistake:
>
>> I expect this output:
>
>[1] 100
>Martin
>Saldo is: 100
>
>but I get
>
>[1] 0
>Martn
>Saldo is: 0
>
>______________________________________________
>[hidden email] mailing list -- To UNSUBSCRIBE and more, see
>https://stat.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide
>http://www.R-project.org/posting-guide.html
>and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Help with first S3-class

Martin Møller Skarbiniks Pedersen
On 3 January 2018 at 08:36, Jeff Newmiller <[hidden email]> wrote:
> Function arguments are not pass-by-reference... they are pass-by-value. You need to return the altered object to the caller when you are done messing with it.

Thanks.
Of course. Now it is working.


> Note that R is a data processing language... your example will not scale to real world use cases because you make no use of vectorization to handle multiple accounts.

> It is better to focus on the functional aspect of computing and let the objects carry the results until you have a chance to summarize or plot them.  Study the "lm" function and associated print and plot methods.

Thanks for these suggestions. It is very helpful.

Regards
Martin

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.