I want to show only parts of an array, that has a long variable name. So far I used:
# Data
k0100_m020_r05_h10000__aea000_aee0$cumsumData = c(-1:10)
# show only parts
k0100_m020_r05_h10000__aea000_aee0$cumsumData[k0100_m020_r05_h10000__aea000_aee0$cumsumData>0]
I wonder if there is a shorter form, since I have to repeat the variable name within the square brackets. Is there a shorter reference to the variable currently used? e.g.:
k0100_m020_r05_h10000__aea000_aee0$cumsumData[_self>0]
Try subset.
subset(k0100_m020_r05_h10000__aea000_aee0, cumsumData > 0)
If you are going to want to look into more than one column an apply approach might be useful:
k0100_m020_r05_h10000__aea000_aee0 <- as.data.frame(matrix(rnorm(25),ncol=5))
apply( k0100_m020_r05_h10000__aea000_aee0 , 2 , function(x) x [ x>0 ] )
#$V1
#[1] 1.5840356 0.2497689
#$V2
#[1] 0.4179352 1.6187143 0.8245239
#$V3
#[1] 0.09328116 0.20761514 0.29894603 2.14484045
#$V4
#[1] 0.4882152 0.4643691 0.5591095
#$V5
#[1] 1.0749748 0.5405291 0.4899797 1.0828021
I am not sure whether this is what you want, but perhaps with() can help:
mask <- with(k0100_m020_r05_h10000__aea000_aee0, _self > 0) # gives you a boolean vector
k0100_m020_r05_h10000__aea000_aee0[mask] # gives you the result
Related
I got some troubles defining array like classes in a way that they are fully typed (as far as that is possible in R).
My example: I want to define a class Avector, which should contain an arbitrary number of elements of the class A.
# Define the base class
setClass("A", representation(x = "numeric"))
# Some magic needed ????
setClass("Avector", ???)
# In the end one should be able to use it as follows:
a1 <- new("A", x = 1)
a2 <- new("A", x = 2)
X <- new("Avector", c(a1, a2))
I am aware that having a vector of objects is not possible in R. So I guess it will be stored in a kind of "typed" list.
I have found some solution, but I am not happy with it:
# Define the vectorized class
setClass(
"Avector",
representation(X = "list"),
valididty = function(.Object)) {
if (all(sapply(.Object#X, function(x) class(x) == "A")))
TRUE
else
"'Avector' must be a list of elements in the class 'A'"
}
)
# Define a method to subscript the elements inside of the vector
setMethod(
"[", signature(x = "Avector", i = "ANY", j = "ANY"),
function(x, i, j, ...) x#X[[i]]
)
# Test the class
a1 <- new("A", x = 1)
a2 <- new("A", x = 2)
avec <- new("Avector", X = list(a1, a2))
# Retrieve the element in index i
avec[i]
This method appears more like a hack to me. Is there a way to do this in a canonical way in R without doing this type checking and indexing method by hand?
Edit:
This should also hold, if the class A is not consisting of atomic slots. For example in the case that:
setClass("A", representation(x = "data.frame"))
I would be glad for help :)
Cheers,
Adrian
The answer depends somewhat on what you are trying to accomplish, and may or may not be possible in your use case. The way S4 is intended to work is that objects are supposed to be high-level to avoid excessive overheads.
Generally, it is necessary to have the slots be vectors. You can't define new atomic types from within R. So in your toy example instead of calling
avec <- new("Avector", X = list(a1, a2))
you call
avec <- new("A", x = c(1, 2))
This may necessitate other slots (which were previously vectors) becoming arrays, for example.
If you're desperate to have an atomic type, then you might be able to over-ride one of the existing types. I think the bit64 package does this, for example. Essentially what you do is make a new class that inherits from, say, numeric and then write lots of methods that supersede all the default ones for your new class.
I am working with 3D arrays. A function takes a 2D array slice (matrix) from the user and visualizes it, using row and column names (the corresponding dimnames of the array). It works fine if the array dimensions are > 1.
However, if I have 1x1x1 array, I cannot extract the slice as a matrix:
a <- array(1, c(1,1,1), list(A="a", B="b", C="c"))
a[1,,]
[1] 1
It is a scalar with no dimnames, hence part of the necessary information is missing. If I add drop=FALSE, I don't get a matrix but retain the original array:
a[1,,,drop=FALSE]
, , C = c
B
A b
a 1
The dimnames are here but it is still 3-dimensional. Is there an easy way to get a matrix slice from 1x1x1 array that would look like the above, just without the third dimension:
B
A b
a 1
I suspect the issue is that when indexing an array, we cannot distinguish between 'take 1 value' and 'take all values' in case where 'all' is just a singleton...
The drop parameter of [ is all-or-nothing, but the abind package has an adrop function which will let you choose which dimension you want to drop:
abind::adrop(a, drop = 3)
## B
## A b
## a 1
Without any extra packages, the best I could do was to apply and return the sub-array:
apply(a, 1:2, identity)
# or
apply(a, 1:2, I)
# B
#A b
# a 1
I need to convert a dataframe to an array of 3 dimensions. All columns in the dataframe are numeric. What is an elegant and/or efficient way to accomplish this?
Example:
x <- 1:3
y <- 1:3
g <- t(vapply(x, function(x){
vapply(y, function(y){
as.numeric(paste(x,y,sep="."))}, numeric(1))}, numeric(3)))
gdf <- data.frame( cbind(rep(1:3,each=3), rbind(g, g*2, g*3)) )
I want to convert "gdf" to an array where gdf$x1 defines the third dimension. The result would look like this:
ga <- array( c(g, g*2, g*3), dim=c(3,3,3) )
Thanks!
This works with your example, I hope it will be general enough for you:
gb <- aperm(array(unlist(gdf[, -1]), c(3, 3, 3)), c(1, 3, 2))
identical(ga, gb)
# [1] TRUE
I also found this way using the package abind:
abind( split(gdf, gdf$X1), along=3)
I would like to store an object in a two-dimensional data structure in R. I have searched and tried several solutions, but none of them do what I want. This is what I had in mind:
S = SomeTwoDimensionalStructure(dim=c(2,4))
S[1,1] = LoadDataObject("File1")
s[1,2] = LoadDataObject("File2")
# etc
FunctionWantingObject(S[1,1])
This solution is quite close, but requires accessing S[[1,1]] instead of S[1,1].
Adding the objects to a list and then using dim resulted in the later functions not being happy with the argument passed.
If you're willing to give your two dimensional structure a new class, you can then define a special [ method for it that does what you want.
## Make sample data, a matrix of lists, of class "listmatrix"
set.seed(44)
m <- matrix(lapply(sample(9), function(X) sample(letters, size=X)), ncol=3)
class(m) <- "listmatrix"
## Define a new `[` method for "listmatrix" objects
`[.listmatrix` <- function(x,i,j,...) `[[`(x,i,j,...)
## Check that it works
m[1,2]
# [1] "m" "f" "h" "y" "r" "x" "q" "k" "n"
(I am definitively using wrong terminology in this question, sorry for that - I just don't know the correct way to describe this in R terms...)
I want to create a structure of heterogeneous objects. The dimensions are not necessary rectangular. What I need would be probably called just "array of objects" in other languages like C. By 'object' I mean a structure consisting of different members, i.e. just a list in R - for example:
myObject <- list(title="Uninitialized title", xValues=rep(NA,50), yValues=rep(NA,50))
and now I would like to make 100 such objects, and to be able to address their members by something like
for (i in 1:100) {myObject[i]["xValues"]<-rnorm(50)}
or
for (i in 1:100) {myObject[i]$xValues<-rnorm(50)}
I would be grateful for any hint about where this thing is described.
Thanks in advance!
are you looking for the name of this mythical beast or just how to do it? :) i could be wrong, but i think you'd just call it a list of lists.. for example:
# create one list object
x <- list( a = 1:3 , b = c( T , F ) , d = mtcars )
# create a second list object
y <- list( a = c( 'hi', 'hello' ) , b = c( T , F ) , d = matrix( 1:4 , 2 , 2 ) )
# store both in a third object
z <- list( x , y )
# access x
z[[ 1 ]]
# access y
z[[ 2 ]]
# access x's 2nd object
z[[ 1 ]][[ 2 ]]
I did not realize that you were looking for creating other objects of same structure. You are looking for replicate.
my_fun <- function() {
list(x=rnorm(1), y=rnorm(1), z="bla")
}
replicate(2, my_fun(), simplify=FALSE)
# [[1]]
# [[1]]$x
# [1] 0.3561663
#
# [[1]]$y
# [1] 0.4795171
#
# [[1]]$z
# [1] "bla"
#
#
# [[2]]
# [[2]]$x
# [1] 0.3385942
#
# [[2]]$y
# [1] -2.465932
#
# [[2]]$z
# [1] "bla"
here is the example of solution I have for the moment, maybe it will be useful for somebody:
NUM <- 1000 # NUM is how many objects I want to have
xVal <- vector(NUM, mode="list")
yVal <- vector(NUM, mode="list")
title <- vector(NUM, mode="list")
for (i in 1:NUM) {
xVal[i]<-list(rnorm(50))
yVal[i]<-list(rnorm(50))
title[i]<-list(paste0("This is title for instance #", i))
}
myObject <- list(xValues=xVal, yValues=yVal, titles=title)
# now I can address any member, as needed:
print(myObject$titles[[3]])
print(myObject$xValues[[4]])
If the dimensions are always going to be rectangular (in your case, 100x50), and the contents are always going to be homogeneous (in your case, numeric) then create a 2D array/matrix.
If you want the ability to add/delete/insert on individual lists (or change the data type), then use a list-of-lists.