Is there any way to programmatically distinguish between package environments and non-package environment objects? For example, the objects x and y below are both environments, with the same class and attributes.
x <- as.environment(cars)
y <- getNamespace("graphics")
However judging from the print method there is a difference:
> print(x)
<environment: 0x1d38118>
> print(y)
<environment: namespace:graphics>
Now suppose I have an arbitrary object, how can I determine which of the two it is (without looking at the output of print)? I would like to know this to determine how to store the object on disk. In case of the former I need to store the list representation of the environment (and perhaps its parents), but for the latter I would just store the name and version of the package.
isNamespace ?
isNamespace(y)
# [1] TRUE
isNamespace(x)
# [1] FALSE
And, for future reference, apropos is often helpful when you've got a question like this.
apropos("namespace")
# [1] "..getNamespace" ".BaseNamespaceEnv" ".getNamespace"
# [4] ".methodsNamespace" "asNamespace" "assignInMyNamespace"
# [7] "assignInNamespace" "attachNamespace" "fixInNamespace"
# [10] "getFromNamespace" "getNamespace" "getNamespaceExports"
# [13] "getNamespaceImports" "getNamespaceInfo" "getNamespaceName"
# [16] "getNamespaceUsers" "getNamespaceVersion" "isBaseNamespace"
# [19] "isNamespace" "loadedNamespaces" "loadingNamespaceInfo"
# [22] "loadNamespace" "namespaceExport" "namespaceImport"
# [25] "namespaceImportClasses" "namespaceImportFrom" "namespaceImportMethods"
# [28] "packageHasNamespace" "parseNamespaceFile" "requireNamespace"
# [31] "setNamespaceInfo" "unloadNamespace"
Related
How can I get a list of the exact names of the objects in the datasets package?
I found many of them here:
data_package = data(package="datasets")
datasets <- as.data.frame(data_package[[3]])$Item
datasets
# [1] "AirPassengers" "BJsales" "BJsales.lead (BJsales)" "BOD" "CO2" "ChickWeight"
# [7] "DNase" "EuStockMarkets" "Formaldehyde" "HairEyeColor" "Harman23.cor" "Harman74.cor"
# [13] "Indometh" "InsectSprays" "JohnsonJohnson" "LakeHuron" "LifeCycleSavings" "Loblolly"
# [19] "Nile" "Orange" "OrchardSprays" "PlantGrowth" "Puromycin" "Seatbelts"
# [25] "Theoph" "Titanic" "ToothGrowth" "UCBAdmissions" "UKDriverDeaths" "UKgas"
# [31] "USAccDeaths" "USArrests" "USJudgeRatings" "USPersonalExpenditure" "UScitiesD" "VADeaths"
# [37] "WWWusage" "WorldPhones" "ability.cov" "airmiles" "airquality" "anscombe"
# [43] "attenu" "attitude" "austres" "beaver1 (beavers)" "beaver2 (beavers)" "cars"
# [49] "chickwts" "co2" "crimtab" "discoveries" "esoph" "euro"
# [55] "euro.cross (euro)" "eurodist" "faithful" "fdeaths (UKLungDeaths)" "freeny" "freeny.x (freeny)"
# [61] "freeny.y (freeny)" "infert" "iris" "iris3" "islands" "ldeaths (UKLungDeaths)"
# [67] "lh" "longley" "lynx" "mdeaths (UKLungDeaths)" "morley" "mtcars"
# [73] "nhtemp" "nottem" "npk" "occupationalStatus" "precip" "presidents"
# [79] "pressure" "quakes" "randu" "rivers" "rock" "sleep"
# [85] "stack.loss (stackloss)" "stack.x (stackloss)" "stackloss" "state.abb (state)" "state.area (state)" "state.center (state)"
# [91] "state.division (state)" "state.name (state)" "state.region (state)" "state.x77 (state)" "sunspot.month" "sunspot.year"
# [97] "sunspots" "swiss" "treering" "trees" "uspop" "volcano"
# [103] "warpbreaks" "women"
So something like this would iterate through each one
for(i in 1:length(datasets)) {
print(get(datasets[i]))
cat("\n\n")
}
It works for the first two datasets (AirPassengers and BJsales), but it fails on BJsales.lead (BJsales) since it should be referred to as datasets::BJsales.lead.
I guess I could use string split or similar to discard anything from a space onwards, but I wonder is there any neater way of obtaining a list of all the objects in the dataset package?
Notes
In addition to the above, I also tried listing everything in the datasets namespace but it gave a weird result:
ls(getNamespace("datasets"), all.names=TRUE)
# [1] ".__NAMESPACE__." ".__S3MethodsTable__." ".packageName"
There is a note on the ?data help page that states
Where the datasets have a different name from the argument that should be used to retrieve them the index will have an entry like beaver1 (beavers) which tells us that dataset beaver1 can be retrieved by the call data(beavers).
So the actual object name is the thing before the parentheses at the end. Since that value is returned as just a string, that's something you'll need to remove yourself unfortunately. But you can do that with a gsub
datanames <- data(package="datasets")$results[,"Item"]
objnames <- gsub("\\s+\\(.*\\)","", datanames)
for(ds in objnames) {
print(get(ds))
cat("\n\n")
}
I have the following vector:
mylist <- c("MBT.LN.ID", "ISA51VG.LN.ID", "R848.LN.ID", "sHz.LN.ID", "FK565.LN.ID",
"bCD.LN.ID", "MALP2s.LN.ID", "ADX.LN.ID", "AddaVax.LN.ID", "FCA.LN.ID",
"Pam3CSK4.LN.ID", "D35.LN.ID", "ALM.LN.ID", "K3.LN.ID", "K3SPG.LN.ID",
"MPLA.LN.ID", "DMXAA.LN.ID", "cGAMP.LN.ID", "Poly_IC.LN.ID",
"cdiGMP.LN.ID")
I'd like to sort them alphabetically in case-insensitive manner.
The expected output is this:
[1] "AddaVax.LN.ID" "ADX.LN.ID" "ALM.LN.ID" "bCD.LN.ID" "cdiGMP.LN.ID" "cGAMP.LN.ID"
[7] "D35.LN.ID" "DMXAA.LN.ID" "FCA.LN.ID" "FK565.LN.ID" "ISA51VG.LN.ID" "K3.LN.ID"
[13] "K3SPG.LN.ID" "MALP2s.LN.ID" "MBT.LN.ID" "MPLA.LN.ID" "Pam3CSK4.LN.ID" "Poly_IC.LN.ID"
[19] "R848.LN.ID" "sHz.LN.ID"
I tried this but failed (Using R.3.2.0 alpha):
> sort(mylist)
[1] "ADX.LN.ID" "ALM.LN.ID" "AddaVax.LN.ID" "D35.LN.ID"
[5] "DMXAA.LN.ID" "FCA.LN.ID" "FK565.LN.ID" "ISA51VG.LN.ID"
[9] "K3.LN.ID" "K3SPG.LN.ID" "MALP2s.LN.ID" "MBT.LN.ID"
[13] "MPLA.LN.ID" "Pam3CSK4.LN.ID" "Poly_IC.LN.ID" "R848.LN.ID"
[17] "bCD.LN.ID" "cGAMP.LN.ID" "cdiGMP.LN.ID" "sHz.LN.ID"
Try
mylist[order(tolower(mylist))]
As noted by #Pascal, this is documented in help(Comparison) and sort is local specific. One Option is switching your local (for example Sys.setlocale("LC_TIME", "us")), but that could be inconvenient. Another option could be using gtools::mixedsort which could be also useful because you string also contains numbers.
library(gtools)
mixedsort(mylist)
# [1] "AddaVax.LN.ID" "ADX.LN.ID" "ALM.LN.ID" "bCD.LN.ID" "cdiGMP.LN.ID" "cGAMP.LN.ID" "D35.LN.ID" "DMXAA.LN.ID" "FCA.LN.ID" "FK565.LN.ID"
# [11] "ISA51VG.LN.ID" "K3.LN.ID" "K3SPG.LN.ID" "MALP2s.LN.ID" "MBT.LN.ID" "MPLA.LN.ID" "Pam3CSK4.LN.ID" "Poly_IC.LN.ID" "R848.LN.ID" "sHz.LN.ID"
> library(searchable)
> sort(ignore.case(mylist))
[1] "AddaVax.LN.ID" "ADX.LN.ID" "ALM.LN.ID" "bCD.LN.ID" "cdiGMP.LN.ID"
[6] "cGAMP.LN.ID" "D35.LN.ID" "DMXAA.LN.ID" "FCA.LN.ID" "FK565.LN.ID"
[11] "ISA51VG.LN.ID" "K3.LN.ID" "K3SPG.LN.ID" "MALP2s.LN.ID" "MBT.LN.ID"
[16] "MPLA.LN.ID" "Pam3CSK4.LN.ID" "Poly_IC.LN.ID" "R848.LN.ID" "sHz.LN.ID"
Is there a way in R to get a list of all methods defined on an S4 class, given the name of that class?
Edit: I know that showMethods can show me all the methods, but I want to manipulate the list programmatically, so that's no good.
Maybe this would be useful:
mtext <- showMethods(class="SpatialPolygons", printTo =FALSE )
fvec <- gsub( "Function(\\:\\s|\\s\\\")(.+)(\\s\\(|\\\")(.+$)",
"\\2", mtext[grep("^Function", mtext)] )
fvec
[1] ".quad" "[" "addAttrToGeom"
[4] "area" "as.data.frame" "click"
[7] "coerce" "coordinates" "coordnames"
[10] "coordnames<-" "coords" "disaggregate"
[13] "extract" "fromJSON" "isDiagonal"
[16] "isTriangular" "isValidJSON" "jsType"
[19] "over" "overlay" "plot"
[22] "polygons" "polygons<-" "rasterize"
[25] "recenter" "spChFIDs" "spsample"
[28] "spTransform" "text" "toJSON"
The original version did not properly extract the quoted non S4 generics in mtext such as:
[60] "Function \"jsType\":"
[61] " <not an S4 generic function>"
Are you looking for showMethods()?
library(sp)
showMethods(class="SpatialPolygons")
Maybe something like
library(sp)
x=capture.output(showMethods(class="SpatialPolygons"))
unlist(lapply(strsplit(x[grep("Function: ",x,)]," "),function(x) x[2]))
Also stumbled upon it, how about
library(sp)
attr(methods(class="SpatialPolygons"), "info")$generic
# Alternatively:
# attr(.S4methods(class="SpatialPolygons"), "info")$generic
This will directly yield a vector of method names.
Given an arbitrary R object, how can I obtain all the methods associated with the object?
The closest I can think of is methods (if S3 object/function, List all available methods for an S3 generic function, or all methods for a class.), or showMethods (if S4).
e.g.:
> A <- matrix(runif(10))
> B <- methods(class=class(A))
> B
[1] anyDuplicated.matrix as.data.frame.matrix as.raster.matrix*
[4] boxplot.matrix determinant.matrix duplicated.matrix
[7] edit.matrix* head.matrix isSymmetric.matrix
[10] relist.matrix* subset.matrix summary.matrix
[13] tail.matrix unique.matrix
Non-visible functions are asterisked
> attr(B,'info')
visible from
anyDuplicated.matrix TRUE package:base
as.data.frame.matrix TRUE package:base
as.raster.matrix FALSE registered S3method
boxplot.matrix TRUE package:graphics
determinant.matrix TRUE package:base
duplicated.matrix TRUE package:base
edit.matrix FALSE registered S3method
head.matrix TRUE package:utils
isSymmetric.matrix TRUE package:base
relist.matrix FALSE registered S3method
subset.matrix TRUE package:base
summary.matrix TRUE package:base
tail.matrix TRUE package:utils
unique.matrix TRUE package:base
Or for a function:
> methods(summary)
[1] summary.aov summary.aovlist summary.aspell*
[4] summary.connection summary.data.frame summary.Date
[7] summary.default summary.ecdf* summary.factor
[10] summary.glm summary.infl summary.lm
[13] summary.loess* summary.manova summary.matrix
[16] summary.mlm summary.nls* summary.packageStatus*
[19] summary.PDF_Dictionary* summary.PDF_Stream* summary.POSIXct
[22] summary.POSIXlt summary.ppr* summary.prcomp*
[25] summary.princomp* summary.srcfile summary.srcref
[28] summary.stepfun summary.stl* summary.table
[31] summary.tukeysmooth*
Non-visible functions are asterisked
?Methods may also prove a useful read.
The class of an R object is recovered with class. Objects do not have methods associated with them in typical R parlance. The class of an object determines what function-methods will be applied to it. In order to determine what functions have methods associated with a given class you would need to test all available functions to see whether there was a class-specific method. Even then generic functions would attempt to use a "default" method in most instances.
Some methods associated with a generic S3 function are displayed with methods. The methods of an S4 function are recovered with showMethods. So, for what most people would call "objects", your question does not make sense, but if it happened that you were including functions under the general term "objects" (which is technically fair) then I have answered.
showMethods(classes="data.frame")
methods(class="data.frame")
Then there are a group of methods that might be called "implicit" although their R name is "groupGeneric"
?groupGeneric
methods("Math") # These are "add-on" methods to the primitive Math functions
[1] Math.data.frame Math.Date Math.dates* Math.difftime Math.factor
[6] Math.mChoice Math.polynomial* Math.POSIXt Math.ratetable* Math.Surv*
[11] Math.times*
Non-visible functions are asterisked
?"+"
methods("Ops") # The binary operators such as "+", "-", "/"
[1] Ops.data.frame Ops.Date Ops.dates* Ops.difftime Ops.factor
[6] Ops.findFn Ops.mChoice Ops.numeric_version Ops.ordered Ops.polynomial*
[11] Ops.POSIXt Ops.raster* Ops.ratetable* Ops.Surv* Ops.times*
[16] Ops.ts* Ops.unit* Ops.yearmon* Ops.yearqtr* Ops.zoo*
Non-visible functions are asterisked
And even then you have not really display the members of the Math or the Ops family, but you would have seen them at the help page for ?groupGeneric. You do not see Ops.numeric. A somewhat lower level view is provided by:
.Primitive("+")
# function (e1, e2) .Primitive("+")
These will throw an error if offered the wrong class argument.
Some packages define functions that are not methods but which are nevertheless intended for use with a particular class. For example, library(igraph) defines the function radius(_), which is intended for use on objects in the igraph class. Since such functions are not methods, methods(_) and showMethods(_) will not reveal them.
In such cases, lsf.str(_) can be very helpful. For example:
lsf.str("package:igraph")
includes the line:
radius : function (graph, mode = c("all", "out", "in", "total"))
Hopefully (one of) the last question on map-files.
Why is this not working, and how would I do that right?
load(url('http://gadm.org/data/rda/CUB_adm1.RData'))
CUB <- gadm
CUB <- spChFIDs(CUB, paste("CUB", rownames(CUB), sep = "_"))
Thank you very much!!!
seems to work with row.names()
load(url('http://gadm.org/data/rda/CUB_adm1.RData'))
CUB <- gadm
CUB <- spChFIDs(CUB, paste("CUB", row.names(CUB), sep = "_"))
The answer is apparent once one reads the help for ?row.names() and ?rownames().
The rownames() function only knows something about matrix-like objects, and CUB is not one of those, hence it doesn't have row names that rownames() can find:
> rownames(CUB)
NULL
row.names() is different, it is an S3 generic function and that means package authors can write methods for specific types of objects such that the row names of those objects can be extracted.
Here is a list of the methods available for row.names() in my current session, with the sp package loaded:
> methods(row.names)
[1] row.names.data.frame
[2] row.names.default
[3] row.names.SpatialGrid*
[4] row.names.SpatialGridDataFrame*
[5] row.names.SpatialLines*
[6] row.names.SpatialLinesDataFrame*
[7] row.names.SpatialPixels*
[8] row.names.SpatialPoints*
[9] row.names.SpatialPointsDataFrame*
[10] row.names.SpatialPolygons*
[11] row.names.SpatialPolygonsDataFrame*
Non-visible functions are asterisked
The class of the object CUB is:
> class(CUB)
[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"
So what is happening is that the SpatialPolygonsDataFrame method of the row.names() function is being used and it knows where to find the required row names.