Using fields from object in for-loop | twitteR - r

I am kind of a newbie to R. I am trying to build a function to retrieve and output all the dimensions. I am using the twitteR package which has an object 'user'. I use the getUser() which outputs a 'user' class type of object. As a part of the twitteR packages documentation, this object is not subsettable but does have fields such as names, screenNames, description, etc., e.g.:
> g <- getUser("CNN")
> g$name
[1] "CNN"
> g$screenName
[1] "CNN"
> g$description
[1] "Bringing you breaking news and the most talked about stories. Join the conversation and let’s connect!"
> g$statusesCount
[1] 35605
> g$followersCount
[1] 10542191
This is my function that I am trying to create and am struggling with:
userInfo <- function(user) {
userDims<- c("name", "screenName", "id", "lastStatus", "description", "statusesCount", "followersCount", "favoritesCount", "friendsCount")
for(i in seq_along(userDims)){
userObj <- getUser(user)
userObj$userDims[i]
}
}
My question is: How do I concatenate userObj$ with each entry in userDim without getting this error:
Error in envRefInferField(x, what, getClass(class(x)), selfEnv) :
‘userDims’ is not a valid field or method name for reference class “user”**

Related

R S4 object datatype hash

Is there a datatype for hash? I tried to genereate a class with datatype character for hash values but I got error:
Error in validObject(.Object) : invalid class "Picture" object: 1:
invalid object for slot "mD5sum" in class "Picture": got class "hash",
should be or extend class "character" invalid class "Picture" object
2: invalid object for slot "sHA1sum" in class "Picture": got class
"hash", should be or extend class "character" Calls: <.....
Generate class code:
setClass("Picture", slots=list(id="numeric", mD5sum="character", sHA1sum="character"))
Adding data to class (this gives error):
md5sum <- as.character(openssl::md5(file(full_file_path)))
sha1sum <- as.character(openssl::sha1(file(full_file_path)))
pic_obj <- new("Picture", id=1, mD5sum=md5sum, sHA1sum=sha1sum)
Full code chunk:
```{r}
setClass("Picture", slots=list(id="numeric", mD5sum="character", sHA1sum="character"))
full_file_path <- "testphoto.JPG"
md5sum <- as.character(openssl::md5(file(full_file_path)))
sha1sum <- as.character(openssl::sha1(file(full_file_path)))
pic_obj <- new("Picture", id=1, mD5sum=md5sum, sHA1sum=sha1sum)
```
No, hash is not an atomic type (the closest idea R has to a "data type"). Hash values (such as from openssl::md5) are generally output as character (though in principle they could be integer if the output was small enough).
If you want to know whether a class exists or not, you can use isClass:
> isClass("hash")
[1] FALSE
> isClass("character")
[1] TRUE

R stm package error: "vectorized sources must have a positive length entry"

I think I'm making a pretty simple mistake but I'm a rookie at R and am having a hard time figuring it out. I'm trying to use the 'stm' package in R do some topic-modeling on a dataset of tweets I scraped.
The dataset is formatted in two columns, one with the name of the tweet-sender, with column header "meta" and the other with the vocab of the tweet, column header, "vocab". After running the script below, I get the following errors:
Error: is.Source(s) is not TRUE
In addition: Warning message:
In is.Source(s) : vectorized sources must have a positive length entry
library(stm)
library(igraph)
setwd("c:/Users/Adam/Desktop/RTwitter")
data <-read.csv("TweetDataSTM.csv")
processed <- textProcessor(data$documents, metadata = data)
out <- prepDocuments(processed$documents, processed$vocab, processed$meta)
docs <- out$documents
vocab <- out$vocab
meta <-out$meta
> library(stm)
> library(igraph)
> setwd("c:/Users/Adam/Desktop/RTwitter")
>
> rm(list=ls())
>
> data <-read.csv("TweetDataSTM.csv")
> processed <- textProcessor(data$documents, metadata = data)
Building corpus...
Error: is.Source(s) is not TRUE
In addition: Warning message:
In is.Source(s) : vectorized sources must have a positive length entry
> out <- prepDocuments(processed$documents, processed$vocab, processed$meta)
Error in prepDocuments(processed$documents, processed$vocab, processed$meta) :
object 'processed' not found
> docs <- out$documents
Error: object 'out' not found
> vocab <- out$vocab
Error: object 'out' not found
> meta <-out$meta
Error: object 'out' not found
(any advice would be greatly appreciated!)
-Adam
I think your mistake occurs because your columns are named vocab and meta. But here
processed <- textProcessor(data$documents, metadata = data)
you are trying to call a column documents that - as far as I see - does not exist in your data.frame. Try changing the code to:
processed <- textProcessor(data$vocab, metadata = data)

‘l’ is no list of MALDIquant::MassPeaks objects

I'm following this tutorial about MALDIquant package but i'm getting an error, before executing this line
peaks <- binPeaks(peaks, tolerance=0.002)
The Error is :
Error: binPeaks(peaks, tolerance = 0.002) : ‘l’ is no list of MALDIquant::MassPeaks objects!
When i do class(peaks) :
> class(peaks)
[1] "MassPeaks"
attr(,"package")
[1] "MALDIquant"
binPeaks just works on list of MassPeaks objects. Your class output shows that you have just a single MassPeaks object.
## load package
library("MALDIquant")
## create two MassPeaks objects
p <- list(createMassPeaks(mass=seq(100, 500, 100), intensity=1:5),
createMassPeaks(mass=c(seq(100.2, 300.2, 100), 395), intensity=1:4))
binnedPeaks <- binPeaks(p, tolerance=0.002)
## but not:
binPeaks(p[[1]])
# Error: binPeaks(peaks, tolerance = 0.002) : ‘l’ is no list of MALDIquant::MassPeaks objects!
Please look at ?binPeaks for details or write me an email (I am the maintainer, you will find my mail address at CRAN.

How to deal with "Warning: object 'xxx' is created by more than one data call"

When checking an R package, I got the warning
Warning: object 'xxx' is created by more than one data call
What causes this, and how can I fix it?
This warning occurs when multiple RData files in the data directory of the package store a variable with the same name.
To reproduce, we create a package and save the cars dataset twice, to different files:
library(devtools)
create("test")
dir.create("test/data")
save(cars, file = "test/data/cars1.RData")
save(cars, file = "test/data/cars2.RData")
check("test")
The output from check includes these lines:
Found the following significant warnings:
Warning: object 'cars' is created by more than one data call
If you receive this warning, you can find repeated variable names using:
rdata_files <- dir("test/data", full.names = TRUE, pattern = "\\.RData$")
var_names <- lapply(
rdata_files,
function(rdata_file)
{
e <- new.env()
load(rdata_file, envir = e)
ls(e)
}
)
Reduce(intersect, var_names)
## [1] "cars"

error-safe templating with brew / whisker

An external program needs an input file with some control parameters, and I wish to generate those automatically using R. Usually, I simply use paste("parameter1: ", param1, ...) to create the long string of text, and output to a file, but the script rapidly becomes unreadable. This problem is probably well suited to whisker,
library(whisker)
template= 'Hello {{name}}
You have just won ${{value}}!
'
data <- list( name = "Chris", value= 124)
whisker.render(template, data)
My issue here, is that there's no safe-checking that data contains all the required variables, e.g.
whisker.render(template, data[-1])
will silently ignore the fact that I forgot to specify a name. My end-program will crash, however, if I fail to produce a complete config file.
Another templating system is provided by brew; it has the advantage of actually evaluating things, and potentially this can also help detect missing variables,
library(brew)
template2 = 'Hello <%= name %>
You have just won $<%= value %>!
'
data <- list( name = "Chris", value= 124)
own_brew <- function(template, values){
attach(values, pos=2)
out = capture.output(brew(text = template))
detach(values, pos=2)
cat(out, sep='\n')
invisible(out)
}
own_brew(template2, data)
own_brew(template2, data[-1]) # error
However, I am stuck with two issues:
attach() ... detach() is not ideal, (gives warnings every now and then), or at least I don't know how to use it properly. I tried to define an environment for brew(), but it was too restrictive and didn't know about base functions anymore...
even though an error occurs, a string is still returned by the function. I tried to wrap the call in try() but I have no experience in error handling. How do I tell it to quit the function producing no output?
Edit: I have updated the brew solution to use a new environment instead of attach(), and stop execution in case of an error. (?capture.output suggests that it was not the right function to use here, since "An attempt is made to write output as far as possible to file if there is an error in evaluating the expressions"...)
own_brew <- function(template, values, file=""){
env <- as.environment(values)
parent.env(env) <- .GlobalEnv
a <- textConnection("cout", "w")
out <- try(brew(text = template, envir=env, output=a))
if(inherits(out, "try-error")){
close(a)
stop()
}
cat(cout, file=file, sep="\n")
close(a)
invisible(cout)
}
There must be an easier way with tryCatch, but I can't understand a single thing in its help page.
I welcome other suggestions on the more general problem.
Using regular expressions to retrieve the variable names from the template, you could validate before rendering, e.g.,
render <- function(template, data) {
vars <- unlist(regmatches(template, gregexpr('(?<=\\{\\{)[[:alnum:]_.]+(?=\\}\\})', template, perl=TRUE)))
stopifnot(all(vars %in% names(data)))
whisker.render(template, data)
}
render(template, data)
The new glue package provides another alternative,
library(glue)
template <- 'Hello {name} You have just won ${value}!'
data <- list( name = "Chris", value= 124)
glue_data(template, .x=data)
# Hello Chris You have just won $124!
glue_data(template, .x=data[-1])
# Error in eval(expr, envir, enclos) : object 'name' not found
Since version 1.1.0 (on CRAN 19 Aug, 2016), the stringr package includes the str_interp() function (unfortunately not mentioned in the NEWS file of the release).
template <- "Hello ${name} You have just won $${value}!"
data <- list( name = "Chris", value= 124)
stringr::str_interp(template, data)
[1] "Hello Chris You have just won $124!"
stringr::str_interp(template, data[-1L])
Error in FUN(X[[i]], ...) : object 'name' not found
While preparing the stringr answer I noticed that OP's questions concerning the usage of brew() hasn't been addressed so far. In particular, the OP was asking how to provide his data to the environment and how to prevent a character string being returned in case of an error.
The OP has created a function own_brew() which wraps the call to brew(). Although, there are alternative package available now, I feel the original question deserves an answer.
This is my attempt to improve baptiste's version:
own_brew <- function(template, values, file=""){
a <- textConnection("cout", "w")
out <- brew::brew(text = template, envir=list2env(values), output=a)
close(a)
if (inherits(out, "try-error")) stop()
cat(cout, file=file, sep="\n")
invisible(cout)
}
The main differences are that list2env() is used to pass the list of values to brew() and that the call to try() is avoided by testing the return value out for an error.
template <- "Hello <%= name %> You have just won $<%= value %>!"
data <- list( name = "Chris", value= 124)
own_brew(template, data)
Hello Chris You have just won $124!
own_brew(template, data[-1L])
Error in cat(name) : object 'name' not found
Error in own_brew(template, data[-1L]) :
The new jinjar package will raise an error if a data variable is missing. It also provides the ability to explicitly handle missing values in your template.
library(jinjar)
# if name missing, raise error
template <- 'Hello {{ name }}
You have just won ${{ value }}!'
render(template, value = 124)
#> Error: [inja.exception.render_error] (at 1:10) variable 'name' not found
# if name missing, use default
template <- 'Hello {{ default(name, "world") }}
You have just won ${{ value }}!'
render(template, value = 124)
#> [1] "Hello world\nYou have just won $124!"
# if name missing, skip section
template <- '{% if exists("name") %}Hello {{ name }}{% endif -%}
You have just won ${{ value }}!'
render(template, value = 124)
#> [1] "You have just won $124!"
Created on 2022-06-25 by the reprex package (v2.0.1)

Resources