I would like to produce x dataframes objects with different names (in the example: df1and df2, which will be based in the loop number.
This is what I tried...
x <- 2
for (k in 1:x){
df[[k]] <- read.table(file=paste(k,"calls.txt", sep=""))
}
I got this error
Object closure is not subsettable
I know that it is a simple syntax problem, but I did not find a solution here.
Any ideas?
You should write it like this
x <- 2
for (k in 1:x){
df[k] <- read.table(file=paste(k,"calls.txt", sep=""))
}
You have to write df[k] instead of df[[k]]
Related
I have got a lot of data frames in my R environment and I want to do the as.numeric() function on all of the variables in the data.frames and overwrite them. I do not know how to address all of them.
The following is my attempt, but ls() seemingly just writes the name to x:
for (i in 1:length(ls())){
x <- ls()[i]
for (i in 1:length(x)){
x[i] <- as.numeric(x[i])
}
}
So, there were two helpful answers to my question. One, that was later deleted and another one by #Henrik.
The deleted one followed my approach to convert all data frames in global environment (that has an "V" in it - in my example) as numerics. This is the code:
res <- lapply(mget(ls(pattern = 'V')), \(x) {
x[] <- lapply(x, as.numeric)
return(x)
})
list2env(res, .GlobalEnv)
# Check
str(VA01.000306__ft2)
The second approach uses lists instead of multiple objects. When I have stored my multiple csv files into lists. This is the csv to list import:
F_EB_names <- list.files(pattern="*.csv")### Daten in Liste speichern?
F_EB <- lapply(F_EB_names, read.csv2)
names(F_EB) <- gsub(".wav.csv","_ft2",F_EB_names)
And this is the conversion to numerals:
F_EB <- type.convert(F_EB) # Conversion
str(F_EB) # Check
Thank you both for the help.
Suppose I have a function which returns me a list of output. How could I call a specific output at once? My original function is difficult and must return my output as a list. Sometimes I need to look at a special output (3 or 5 of them (out of 10). How can I do that very quickly using a shortcut code instead of repeating it several times to get one output each time?
For example,
x <- rnorm(1:5)
y <- rnorm(1:5)
myfun <- function(x,y){
mult <- sumf <- distfu <- list()
for(i in 1:5){
mult[[i]] <- x[[i]]*y[[i]]
sumf[[i]] <- x[[i]]+y[[i]]
distfu[[i]] <- x[[i]]-y[[i]]
}
out <- list()
out$mult <- mult
out$sumf <- sumf
out$distf <- distfu
return(out)
}
myres <- myfun(x,y)
How can I call myres$multand
myres$distf only at one time?
I tried this: myres$[c(1,3)] but it was wrong.
Please note that this example is simple, however, my function returns more than 10 outputs. So, if I need to only look at 5 of them, then I need to repeat this myfun$.. five times. I just would like to know if there is a way to call all the 5 outputs at once`.
To call a specific elements of a list you must do it like this:
myres[c(1,3)]
In your code there was a typo $ after myres
I hope this will help you.
I am using the extract function in a loop. See below.
for (i in 1:length(list_shp_Tanzania)){
LU_Mod2000<- extract(x=rc_Mod2000_LC, y=list_shp_Tanzania[[i]], fun=maj)
}
Where maj function is:
maj <- function(x){
y <- as.numeric(names(which.max(table(x))))
return(y)
}
I was expecting to get i outputs, but I get only one output once the loop is done. Somebody knows what I am doing wrong. Thanks.
One solution in this kind of situation is to create a list and then assign the result of each iteration to the corresponding element of the list:
LU_Mod2000 <- vector("list", length(list_shp_Tanzania))
for (i in 1:length(list_shp_Tanzania)){
LU_Mod2000[[i]] <- extract(x=rc_Mod2000_LC, y=list_shp_Tanzania[[i]], fun=maj)
}
Do not do
LU_Mod2000 <- c(LU_Mod2000, extract(x=rc_Mod2000_LC, y=list_shp_Tanzania[[i]], fun=maj))
inside the loop. This will create unnecessary copies and will take long to run. Use the list method, and after the loop, convert the list of results to the desired format (usually using do.call(LU_Mod2000, <some function>))
Alternatively, you could substitute the for loop with lapply, which is what many people seem to prefer
LU_Mod2000 <- lapply(list_shp_Tanzania, function(z) extract(x=rc_Mod2000_LC, y=z, fun=maj))
I have some data.frames
dat1=read.table...
dat2=read.table...
dat3=read.table...
And I would to count the rows for each data set. So
the names are saved like this (cannot "change" it) vector=c("dat1","dat2","dat3...)
p <- vector(numeric, length=1:length(dat))
counting <- function(x) {for (i in 1:x){
p[i]<-nrow(dat[i])}
return(p)
}
This is not working because the input for nrow is a character, but i need integer(?) or?
Thx for help
You can use get for this, but be careful! Instead reading the tables at a list is the R-ish way:
file.names <- list.files()
dat <- lapply(file.names, read.table)
Then you have all the conveniences of lapply and the apply family at your disposal, e.g.:
lapply(dat, nrow)
The solution using get (also vector is a bad variable name since its a very important function):
lapply(vector, function(x) nrow(get(x)))
Your method fails since there is no object called dat to index into. The for loop could look like:
p = NULL
for(v in vector) {
p <- c(p, nrow(get(v)))
}
But that technique is poor form for lotsa reasons...
If you want to determine properties of items you know to be in the .GlobalEnv, this works:
> sapply( c("A","B"), function(objname) nrow(.GlobalEnv[[objname]]) )
A B
5 4
You could substitute any character vector for c("A","B")`. If the object is not in the global environment it just returns NULL, so it's reasonably robust.
A previous post provided a solution to iteratively store plots in R: see ... iteratively in R... . I had a similar problem and after reading and implementing the solutions provided by the post I am still unable to solve my problem.
The previous post provided the following code:
# Create a list to hold the plot objects.
pltList <- list()
for( i in 2:15 ){
# Get data, perform analysis, ect.
# Create plot name.
pltName <- paste( 'a', i, sep = '' )
# Store a plot in the list using the
name as an index.
pltList[[ pltName ]] <- plot()
}
The following is my code implementation:
a <- list.files("F:.../4hrs", pattern='.csv')
pltList <- list()
i=1
for (x in a) {
myfiles <- read.csv(a, header=TRUE, as.is=TRUE, nrows=2500)
h <- hist(data, plot=F)
# perform analysis, ect.
pltName <- paste('a', formatC(i, width=2, flag='0'), sep='')
pltList[[ pltName ]] <- plot(h)
i <- i+1
}
pltName does produce a list of names but pltList is of length zero.
I am not sure why pltList is not being assigned the plots.
What I eventually want to do is create a pltList with multiple plots contained therein. Then plot those plots in par(mfrow=c(2,1)) style and export as a .pdf.
I should mention that the above works for
pltList[[ pltName ]] <- xyplot(h)
but then I am unable to plot multiple plots in the style of par(mfrow=c(2,1)).
Any suggestions are appreciated.
In the original question you referenced and my answer to it, plot() was used as an abstract placeholder for a plotting function that returned an object and not a literal call to the R function plot. Most functions that return graphics objects are based on the 'grid' package such as xyplot from the lattice package or qplot from ggplot2.
Sorry for the confusion, I should have made this point clear in my answer, but I did not as the asker of the question was already aware of it.
Base graphics functions such as hist and plot render directly to output and do not return any objects that can be used to recreate the plot at a later time which is why you are ending up with a list of length zero.
In order to use this approach you will have to trade usage of the hist function for something that returns an object. Using ggplot2, you could do something like the following in your loop:
# Don't call your data variable 'data' or ggplot will confuse it with the
# `data` function and suffer an error.
h <- qplot(x = plot_data)
pltName <- paste('a', formatC(i, width=2, flag='0'), sep='')
pltList[[ pltName ]] <- h
I have edited my answer to the previous question to make it clear that the use of plot() in my example is not an actual call to the R function of the same name.
Your code uses files I don't have so I can't replicate it, I am also not entirely sure what you are trying to accomplish, but I do see some problems in the code that might help fix it:
a <- list.files("F:.../4hrs", pattern='.csv')
I am not fammiliar with list.files, Is this correctly assigning a? .csv seems an odd pattern.
pltList <- list()
i=1
for (x in a) {
myfiles <- read.csv(a, header=TRUE, as.is=TRUE, nrows=2500)
Here I think a is a vector containing the filenanes right? You are looping x for every value of a, however I don't see x return anywhere in the code. Also you are reading a vector of filenames here. Shouldnt this be read.csv(x,..., or better yet, loop for (i in 1:length(a)) and index a[i].
h <- hist(data, plot=F)
I don't see the object data anywhere. Is h correctly assigned?
# perform analysis, ect.
pltName <- paste('a', formatC(i, width=2, flag='0'), sep='')
pltList[[ pltName ]] <- plot(h)
i <- i+1
}
What I like to do is simply run such a loop by hand, and see what is going on. I think there is a problem in the assigning of myfiles or h