R: syntax of svychisq and summary on a svytable - r

I'm working on a "svydesigned" database and having trouble using svysq.
Here's what I tried which worked:
AxB<-svytable(~A+B, surveydesign, Ntotal=100)
AxB
svychisq(~A+B, surveydesign)
And what I would like to make work:
svychisq(AxB, surveydesign)
returns "$ operator is invalid for atomic vectors"
svychisq(~AxB, surveydesign)
returns "Error in formula [[2]][[2]] : Object of type symbol is not subsettable"
summary(AxB)
returns the table and the chisq, but with integers in the table (so only 0 and 1 since my values are in 0.xx format due to Ntotal=100)
What bugs me is that the help states that "sumary on svytable calls svychisq". I'm still new to R syntax and can't figure out how to make svychisq return a result using the table instead of typing again the whole formula I just used to create the table.
I'd also like to be able to see the decimals when usign "summary", is there a way? I tried to use digits=4 but nothing changed.
Thanks.

svychisq expects a formula and a svydesign object as arguments. It is just the way it was created, you won't be able to feed it a svytable argument. You could work around by writing your own function:
FOO <- function(x){
temp <- as.character(attr(x, "call"))[2:3]
svychisq(as.formula(temp[1]), design = eval(parse(text = temp[2])))
}
You feed it a svytable object, it retrieves the call of the object and feeds it back to svychisq.
FOO(AxB) should work as expected.

Related

Running a MCMC analysis with a new tree I made using BM, anyone know what this error would mean?

tree_mvBM <- read.nexus("C:/Users/Zach/Desktop/tree_mvBM.tre")
View(tree_mvBM)
dat <- data$Tp; names(dat) <- rownames(data)
Error in data$Tp : object of type 'closure' is not subsettable
You're trying to refer to an object called data in your global workspace, presumably a data frame. The object doesn't exist (you forgot to read it in,or you called it something else, or ... ?), so R is instead finding the built-in function data. It is trying to "subset" it (i.e. $Tp tells R to extract the element named "Tp"), which is not possible because you can't extract an element of a function. (Functions are called "closures" in R for technical reasons.)
This is one reason (probably the main reason) that you shouldn't give your variables names that match the names of built-in R objects (like I, t, c, data, df, ...). If you had called your data my_data instead the error message would be
Error: object 'my_data' not found
which might be easier to understand.
This is such a common error that there are jokes about it (image search the error message):

R parLapply: How to (or Can we) access an object within the parallel code

I am trying to use parLapply to run a custom function. Since my actual code and data is not very reader friendly, I am creating a pseudo code for reference. I do the following:
a) First, I create a custom function. This function takes an argument say "Argument1". Argument1 is a list object which is what I use to run the parLapply on later.
b) Inside the function, based on Argument1, I create a subset called subset_data (subsetting on the full dataset which is supplied while calling parLapply).
c) After getting subset_data, I obtain a list of unique items for Variable2 and then further subset it depending on the number of unique items in Variable2.
d) Finally I run a function (SomeOtherFunction) which takes subset_data2 as the argument.
SomeCustomFunction = function(Argument1){
subset_data = OriginalData[which(OriginalData$Variable1==Argument1),]
some_other_variable = unique(subset_data$Variable2)
for (object in some_other_variable){
subset_data2 = subset_data[which(subset_data$Variable2 == object),]
FinalOutput = SomeOtherFunction(subset_data2)
}
return(SomeOutput)
}
SomeOtherFunction=function(subset_data2){
#Do Some computation here
}
Next I can create clusters in this way:
cl=parallel::makeCluster(2,type="PSOCK")
registerDoParallel(cl)
And supply the objects Argument1, OriginalData by calling clusterExport and then finally run parLapply by supplying SomeCustomFunction and a list for Argument1 (suppose Argument1_list).
clusterExport(cl=cl, list("Argument1","OriginalData"),envir=environment())
zz=parLapply(cl=cl,fun=SomeCustomFunction,Argument1=Argument1_list)
However, in this case, when I run parLapply, I get an error saying
Error in get(name, envir = envir) : object 'subset_data2' not found
In this case, I was assuming that since subset_data2 is being created within the first function, the object subset_data2 will get supplied automatically. Clearly this is not happening.
Is there a way for me supply this 2nd subset (subset_data2) within the function SomeCustomFunction without passing it to the cluster when calling ClusterExport?
If the question is not clear, please let me know and I can modify it accordingly. Thanks in advance.
P.S. I read this question: using parallel's parLapply: unable to access variables within parallel code, but in my case I do not call parLapply inside my function.
In the related question you mention, the top answer passes clusterExport a character vector of variable names, whereas you pass a list. Also, help(clusterExport) reveals: "varlist: character vector of names of objects to export".
Also, you're missing a " after Argument1 here: list("Argument1,"OriginalData, but I'm guessing that's only the sample code you posted, not in your real code.
PS: It's a step in the right direction that you put some code, but your question will get more responses if you put sample data and code that can be directly pasted and run to reproduce the error.

Conditional within a loop in R: doesn't recognize loop object (i) and throws error: there is no object called 'i' [duplicate]

I want to create a function which includes loading a package that I make within the function. A short example (which doesn't run!):
loadMe <- function(name){
genLib(xxx, libName = name) #make a new library with name "name"
library(name) #load the new library...
}
This does not work! A bit of reproducible code which illustrates my main problem:
library(ggplot) #this works fine
load.this <- "ggplot"
library(load.this) #I want this to load ggplot!
I know the problem is that library() and require() take as an argument an object name which does not exist yet. I have tried wrapping my character string with parse(), deparse(), substitute(), expression(), quote(), etc etc. These all return the same problem:
library(load.this)
# Error in library(loadss) : there is no package called 'loadss'
library(deparse(load.this))
# Error in library(deparse(loadss)) : 'package' must be of length 1
Is there a way to do this?
Use the character.only argument
foo <- "ggplot2"
library(foo,character.only=TRUE)
You say that you have tried using parse(). The following seems to work for me:
eval(parse(text = 'library(MASS)')[1])

Calling objects from list

I'm having some trouble calling an object from a list, from a created variable within my for loop.
for (i in 1:10)
{
#create variables and run through function
varName<-paste("var",i,sep="")
assign(varName, rnmf(data, k=i, showprogress=FALSE))
#create new variable using object 3 from varName output
varNF<-paste("varNF",i,sep="")
assign(varNF, (data-varName[[3]])^2)
}
My problem is with the second part of my for loop. I am attempting to use the third object from the output of my first created variable, in the calculation of my second variable. If I use varName[[3]] I get "subscript out of bounds", and if I use varName$fit, I get "$ operator is invalid for atomic vectors".
It looks like varName in my second part is not calling the incrementing varName (var1, var2, var3, etc...) that I am creating, but it is calling the actual variable varName. To try and get around that, I instead tried
assign(varNF, (data-get(paste("var",i,"[[3]]",sep="")))^2)
Which gave me the error "object 'var1[[3]]' not found". But, if I simply call var1[[3]] in my R console, it does exist. I'm not quite sure where to go from here. Any help would be great!
A very useful rule of thumb in R is:
If you find yourself using either assign() or get() in your code, it's a strong indicator that you are approaching the problem with the wrong tools. If you still think you should use those functions, think again. The tools that you are missing are most likely R lists and subsetting of lists.
(and tell everyone that you know about the above)
In your case, I would do something like:
library("rNMF")
[...]
var <- list()
varNF <- list()
for (i in 1:10) {
res <- rnmf(data, k = i, showprogress = FALSE)
var[[i]] <- res
varNF[[i]] <- (data - res$fit)^2
}

Searching a functions source code

In R, you can view the source of a function as a function is simply another object.
I am looking for a way to search through this source code, without knowing the file that the source is saved in.
For example, I might want to know if the function shapiro.test contains the function sort (it does).
If shapiro.test was a string or a vector of strings I would use
grep('sort', shapiro.test)
But as shapiro.test is a function, this gives the error "Error in as.character(x) :
cannot coerce type 'closure' to vector of type 'character'".
I've had no luck trying to coerce the function to a string. Just as an extra, I'm not expecting to be able to search through base functions as they are compiled.
Here a solution using deparse:
> grep ("sort", deparse(shapiro.test))
[1] 5
You could wrap the function in capture.output, which will convert each line to an element in a character vector.
> grep("sort",capture.output(shapiro.test))
[1] 5
Or you could just call edit(shapiro.test) and use the text editor specified by options(editor=) to search through the function.

Resources