On Jun 25, 2015, at 7:48 PM, Steven Yen wrote:> Thanks to all for the help. I have learned much about "inherit" and "class". I like to know about one additional option, and that is to use a calling parameter without the quotation marks, similar to the linear regression syntax: > > lm(data=mydata,weights=wt) > > Below is a simple set of codes to calculate weighted means with generated data in data frame "mydata". As annotated below, I like the following call to work (without the quotations): > > wmean(mydata,wt=weight)Let's start with the call. If you are to execute this, then names `mydata` and `weight` each must have a value.> > Thank you! > ---- > > mydata<-matrix(1:20,ncol=2)OK. There is a value having been assigned to `mydata`> mydata<-cbind(mydata,runif(10,0,1))And now augmented.> colnames(mydata)<-c("y","x","weight")And a names attribute added for its columns.> mydata<-as.data.frame(mydata) > > wmean <- function(data,wt){ > if (inherits(wt,what="character")) wt<-data[,wt] > wt<-wt/mean(wt)Here's the problem. If `wt` was of mode "character", then you cannot divide it by a number, since the RHS will be evaluated first. You really should read the error messages! Perhaps you meant: wt <- data[, wt]/mean(data[ , wt] But if you did, then it's rather confusing (but possible) to assign the value to the same name as the column of the matrix.> Mean<-NULLWhy do that? If you remove it from the workspace then you cannot assign a value using indexed assignment as you apparently intend to do. Should have been Mean <- numeric( ncol(data) )> for (i in 1:ncol(data)){ > Mean[i] <- sum(data[,i]*wt)/sum(wt)There is a bit of a confusion here. `wt` started out as a character value. I guess you could do this.> } > list("Mean: ",Mean)Wrong syntax for lists. Suspect you want list(Mean=Mean)> } > wmean(mydata,wt="weight") # This works > wmean(mydata,wt=weight) # <= Like this to workSo were you planning to execute this first? weight="weight" #? -- David.> reg<-lm(data=mydata,weights=weight) # ? lm > > On 6/24/2015 3:20 AM, Martin Maechler wrote: >>>>>>> Steve Taylor <steve.taylor at aut.ac.nz> >>>>>>> on Wed, 24 Jun 2015 00:56:26 +0000 writes: >> >> > Note that objects can have more than one class, in which case your == and %in% might not work as expected. >> >> > Better to use inherits(). >> >> > cheers, >> > Steve >> >> Yes indeed, as Steve said, really do! >> >> The use of (class(.) == "....") it is error prone and >> against the philosophy of classes (S3 or S4 or ..) in R : >> >> Classes can "extend" other classes or "inherit" from them; >> S3 examples in "base R" are >> - glm() objects which are "glm" >> but also inherit from "lm" >> - multivariate time-series are "mts" and "ts" >> - The time-date objects POSIXt , POSIXct, POSIXlt >> >> ==> do work with inherits(<obj>, <class)) >> or possibly is( <obj>, <class>) >> >> >> We've seen this use of >> >> class(.) == ".." (or '!=" or %in% ...) >> >> in too many places; though it may work fine in your test cases, >> it is wrong to be used in generality e.g. inside a function you >> provide for more general use, >> and is best replaced with the use of inherits() / is() >> everywhere "out of principle". >> >> Martin Maechler >> ETH Zurich >> > > -- > Steven Yen > My e-mail alert: > https://youtu.be/9UwEAruhyhY?list=PLpwR3gb9OGHP1BzgVuO9iIDdogVOijCtO > > ______________________________________________ > R-help at r-project.org 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.David Winsemius Alameda, CA, USA
Thanks Davis. But actually, the line is legitimate: if (inherits(wt,what="character")) wt<-data[,wt] because, coming down with wt being characters, the part wt<-data[,wt] then picks up variables data$wt. The call wmean(mydata,wt="weight") actually goes OK. I was hoping to figure out a way to fix the wmean routine some how so that I can call with wmean(mydata,wt=weight) Good to know there is a better way to initialize the vector Mean and and a better list command. Thank you! On 6/26/2015 2:39 AM, David Winsemius wrote:> > On Jun 25, 2015, at 7:48 PM, Steven Yen wrote: > >> Thanks to all for the help. I have learned much about "inherit" and "class". I like to know about one additional option, and that is to use a calling parameter without the quotation marks, similar to the linear regression syntax: >> >> lm(data=mydata,weights=wt) >> >> Below is a simple set of codes to calculate weighted means with generated data in data frame "mydata". As annotated below, I like the following call to work (without the quotations): >> >> wmean(mydata,wt=weight) > > Let's start with the call. If you are to execute this, then names `mydata` and `weight` each must have a value. > >> >> Thank you! >> ---- >> >> mydata<-matrix(1:20,ncol=2) > > OK. There is a value having been assigned to `mydata` > >> mydata<-cbind(mydata,runif(10,0,1)) > > And now augmented. > >> colnames(mydata)<-c("y","x","weight") > > And a names attribute added for its columns. > >> mydata<-as.data.frame(mydata) >> >> wmean <- function(data,wt){ >> if (inherits(wt,what="character")) wt<-data[,wt] >> wt<-wt/mean(wt) > > Here's the problem. If `wt` was of mode "character", then you cannot divide it by a number, since the RHS will be evaluated first. You really should read the error messages! > > Perhaps you meant: > > wt <- data[, wt]/mean(data[ , wt] > > But if you did, then it's rather confusing (but possible) to assign the value to the same name as the column of the matrix. > > >> Mean<-NULL > > Why do that? If you remove it from the workspace then you cannot assign a value using indexed assignment as you apparently intend to do. Should have been > > Mean <- numeric( ncol(data) ) > > >> for (i in 1:ncol(data)){ >> Mean[i] <- sum(data[,i]*wt)/sum(wt) > > There is a bit of a confusion here. `wt` started out as a character value. I guess you could do this. > >> } >> list("Mean: ",Mean) > > Wrong syntax for lists. Suspect you want > > list(Mean=Mean) > > >> } >> wmean(mydata,wt="weight") # This works >> wmean(mydata,wt=weight) # <= Like this to work > > So were you planning to execute this first? > > weight="weight" #? >-- Steven Yen My e-mail alert: https://youtu.be/9UwEAruhyhY?list=PLpwR3gb9OGHP1BzgVuO9iIDdogVOijCtO
On Jun 25, 2015, at 11:52 PM, Steven Yen wrote:> Thanks Davis. But actually, the line is legitimate:I didn't say it was illegitimate, only confusing.> > if (inherits(wt,what="character")) wt<-data[,wt]What you are asking for is known in R as non-standard evaluation. Examples include the library and help functions. About a page and a half down the code for `help`, you see this line, following a tryCatch test to see if the argument is character: stopic <- deparse(substitute(topic)) That returns a character value from a symbol. About three pages inside the code for `library` you also see this after a test for 'character'-ness: package <- as.character(substitute(package)) -- David.> > because, coming down with wt being characters, the part wt<-data[,wt] then picks up variables data$wt. The call > > wmean(mydata,wt="weight") > > actually goes OK. I was hoping to figure out a way to fix the wmean routine some how so that I can call with > > wmean(mydata,wt=weight) > > Good to know there is a better way to initialize the vector Mean and and a better list command. Thank you! > > On 6/26/2015 2:39 AM, David Winsemius wrote: >> >> On Jun 25, 2015, at 7:48 PM, Steven Yen wrote: >> >>> Thanks to all for the help. I have learned much about "inherit" and "class". I like to know about one additional option, and that is to use a calling parameter without the quotation marks, similar to the linear regression syntax: >>> >>> lm(data=mydata,weights=wt) >>> >>> Below is a simple set of codes to calculate weighted means with generated data in data frame "mydata". As annotated below, I like the following call to work (without the quotations): >>> >>> wmean(mydata,wt=weight) >> >> Let's start with the call. If you are to execute this, then names `mydata` and `weight` each must have a value. >> >>> >>> Thank you! >>> ---- >>> >>> mydata<-matrix(1:20,ncol=2) >> >> OK. There is a value having been assigned to `mydata` >> >>> mydata<-cbind(mydata,runif(10,0,1)) >> >> And now augmented. >> >>> colnames(mydata)<-c("y","x","weight") >> >> And a names attribute added for its columns. >> >>> mydata<-as.data.frame(mydata) >>> >>> wmean <- function(data,wt){ >>> if (inherits(wt,what="character")) wt<-data[,wt] >>> wt<-wt/mean(wt) >> >> Here's the problem. If `wt` was of mode "character", then you cannot divide it by a number, since the RHS will be evaluated first. You really should read the error messages! >> >> Perhaps you meant: >> >> wt <- data[, wt]/mean(data[ , wt] >> >> But if you did, then it's rather confusing (but possible) to assign the value to the same name as the column of the matrix. >> >> >>> Mean<-NULL >> >> Why do that? If you remove it from the workspace then you cannot assign a value using indexed assignment as you apparently intend to do. Should have been >> >> Mean <- numeric( ncol(data) ) >> >> >>> for (i in 1:ncol(data)){ >>> Mean[i] <- sum(data[,i]*wt)/sum(wt) >> >> There is a bit of a confusion here. `wt` started out as a character value. I guess you could do this. >> >>> } >>> list("Mean: ",Mean) >> >> Wrong syntax for lists. Suspect you want >> >> list(Mean=Mean) >> >> >>> } >>> wmean(mydata,wt="weight") # This works >>> wmean(mydata,wt=weight) # <= Like this to work >> >> So were you planning to execute this first? >> >> weight="weight" #? >> > > -- > Steven Yen > My e-mail alert: > https://youtu.be/9UwEAruhyhY?list=PLpwR3gb9OGHP1BzgVuO9iIDdogVOijCtODavid Winsemius Alameda, CA, USA