I am attempting to count all the instances across a list of data frames where a certain variable is over a given value. I have tried to do it as so:
for (name in myList){
nrow(subset(myList[[name]], var >=6))
}
as I found here: http://www.statisticsblog.com/2010/03/r-tip-iterating-over-list/
However, I get the following error:
Error in myList[[name]] : invalid subscript type 'list'
I know that nrow works because I have used it on a specific list item outside of the loop and it succeeded. I can't seem to figure out why the error is arising. The list names are set up as so:
myList$`i.j.k`
with i, j, and k each taking on a different numerical value. I generated the list as so from a data frame read in from a .csv file:
myList <- split(data, f=list(data$i, data$j, data$k))
What is causing the error? Or, is there a better way to do a conditional count across all list elements (there are 2000+ of them, so any non-loop way would be ideal). Thanks!
I figured it out thanks to the comment from #PoGibas:
Rather than
for (name in myList){
nrow(subset(myList[[name]], var >=6))
}
it should be:
for (name in myList){
nrow(subset(name, var >=6))
}
Related
I'm trying to create a loop that goes from 1 to 14. Each integer in this loop would be added to the end of the name of a newly created dataframe. Then, it should search a column in an existing dataframe based on the concatenation of a number and text. I've been searching for hours but cannot find a solution.
What I mean is:
while (i <= 14) {
"newDF" + i <- oldDf %>%
filter(str_detect(ColumnName, "TEXT" + i)
}
The new dataframes should look like this:
newDF1,newDF2... newDF14
They should be created based on a concatenated string (text + i):
text1,text2..text14
My first challenge is to create a new dataframe based on the concatenation of text and i. I've tried using the str_c command and the str_glue command but get the following error message.
Error in str_c("newDF", i)) <- oldDF:
target of assignment expands to non-language object
Error in str_glue("newDF{i}") <- oldDF:
target of assignment expands to non-language object
The major problem with your code above is that you can't have any operations to the left of your assignment operator.
for (i in 1:14){
assign(str_glue("newDF{i}"), oldDF %>%
filter(str_detect(ColumnName, str_glue("TEXT{i}"))))
}
So technically, this would work even though I feel like there's a better way to do this either with nested lists or using spread and gather. I would say more, but I don't have enough context to solve the problem.
I have the below function which inserts a row into a table (new_scores) based upon the attribute that I feed into it (where the attribute represents a table that I select things from):
buildNewScore <- function(x) {
something <- bind_rows(new_scores,x%>%select(ATT,ADJLOGSCORE))
return(something)
}
Which works fine when I define x.
But when I try to create a for loop that feeds the rest of my attributes into the function it falls over as I'm feeding in a character.
attlist <- c('Z','Y','X','W','V','U','T','RT','RO')
record_count <- length(attlist)
for (x in c(1:record_count)){
buildNewScore(attlist[x])
}
I've tried to convert the attribute into other classes but I can't get the loop to use anything I change it to (name, data.frame etc.).
Anyone have any ideas as to where I'm going wrong - is my attlist vector in the wrong format?
Thanks,
Spikelete.
I'd like to loop through a list of files and record detailed info about them (size, no. of rows, means of columns).
I just started with storing the info in a data frame:
df<-data.frame()
all <-list.files(pattern=".csv")
for (i in all){
file<-read.csv(i)
filas<-nrow(file)
cols<-ncol(file)
info<-c(i,filas,cols)
df<-rbind(df,i,filas,cols)
}
but it triggers an error caused by the 'i' variable, which is just a file name. What am I doing wrong?
Thanks in advance, p.
Don't use for loops. Rather, use lapply in combination with do.call to obtain your desired result. Try:
do.call(rbind,lapply(all,function(x) {y<-read.csv(x); c(file=x, filas=nrow(y), cols=ncol(y))}))
Your approach was failing because in order of rbind to work, you need two data.frames with the same number of columns. You initially have created an empty data.frame (with 0 column) and this couldn't be rbinded to a vector of length 3 (assuming that you want a row for each file showing file name, number of rows and number of columns). If you really want to use a for loop, you should do something like:
for (i in 1:length(all)) {
file<-read.csv(all[i])
info<- data.frame(file=all[i], filas=nrow(file), cols=ncol(file))
if (i==1) df<-info else df<-rbind(df,info)
}
I am trying to create an r loop to run a command on a series of datasets. the command is make.design.data from the RMark library. The only argument it takes is the name of a list. I have 17 of these lists I'd like to pass to make.design.data This is the code I've been trying to use
DFNames<-c("DFAmerican.Goldfinch", "DFAmerican.Robin","DFBarn.Swallow","DFBobolink", "DFBrown.head.Cowbird", "DFCedar.Waxwing", "DFCommon.Grackle","DFCommon.Yellowthroat", "DFEuropean.Starling","DFHorned.Lark", "DFKilldeer","DFRed.wing.Blackbird", "DFSavannah.Sparrow", "DFSong.Sparrow","DFTree.Swallow", "DFVesper.Sparrow", "DFYellow.Warbler")
#in my environment each of the names given to DFNames represents a list
for (x in DFNames){
n<-make.design.data(x)
assign(paste0("ddl",x),n)
}
this gives me the error
Error in data$model : $ operator is invalid for atomic vectors
can anyone please suggest a way to fix my code, or a different way of tackling this?
Thanks, Jude
Instead, you can make a list of the actual data sets instead of a vector of their names.
x <- list(DFAmerican.Goldfinch, ...)
Then you can use:
lapply(x, make.design.data)`.
Or use get inside your for loop:
for (x in DFNames) {
make.design.data(get(x))
}
The "R" way is the former using lists and the apply family. Then you can avoid the gymnastics of assign.
Assume:
list of n xts objects in .GlobalEnv with the suffix ".raw" (e.g: ABC.raw)
have created a list of .raw names in a list (ie, rawfiles <- ls(pattern="*.raw",envir=.GlobalEnv))
Would like to:
loop or lapply through rawfiles and subset a particular timeperiod in each iteration
for example, to write this as a single line would be: new <- ABC.raw["T09:00/T10:00"] if I wanted to subset ABC.raw from 9am to 10am each day.
The problem is:
Doesn't seem to be an easy way of passing["Thh:mm/Thh:mm"] to a loop, apply or assign without causing errors.
Any ideas how to pass this?
In pidgeon code, I guess I'm looking for a working equivalent of:
for(i in 1:length(raw)){
raw[i]["T09:00/T10:00"]
}
Many thanks in advance for any assistance on this.
Try get.
get(x) retrieves the variable whose name is stored in x, so foo<-1; get('foo') would return 1.
for ( rawname in rawfiles ) {
get(rawname)["T09:00/T10:00"]
}