Friday, January 13, 2012

R tips - Using For loops in R

Using For loops in R significantly shortens your scripts. After all the process is pretty simple, and maybe because of that the tips for the topic are rather scattered. It is kind of assumed that everyone can do these loops. However, for us who have no programming background the philosophy behind these loops is rather unfamiliar. In this post I'll try to clarify usage of for loos in R with some simple examples.

The anatomy of a for loop is following:

for(for loop parameter in start (number):end (number)){
actual script using for loop parameter
}

You can replace for loop parameter with any name (numbers are not allowed). For some reason people often use i,j,l or k. This is fine, but by all means a,f,g,blurp or fk will work as well. I like to use letters, because they are short and require less writing.

Start (number) and end (number) must be replaced with either a number or with a function that returns a number. For example ncol(x), ncol(x)-1, length(x)/mean(x$y) and grep("column name", colnames(x)) are all fine as long as they make sense for you. x is your data frame here.

Essentially you should write a script that does the process you want to loop once. In this script you'll have to use column, row or vector element numbers instead of names. Then you'll just replace the number with a for loop parameter. Let's get started:

data(CO2)


df <- data.frame(CO2)


str(df)


# I want to change the class of all columns to "factor". I'd do it following, if I used column numbers:


df[,1] <- as.factor(df[,1])


# Then it's just to replace "1" with a For loop parameter:



for(i in grep("conc", colnames(df)):ncol(df)){
df[,i] <- as.factor(df[,i])}


# Here I used grep command to start the loop from the 4th column, since columns 1-3 are already factors.


str(df)



# You can do a lot of things with these loops. For example, make multiple figures:


df <- data.frame(CO2)
x <- levels(df$Plant)


for(i in 1:length(x)){
y <- df[df$Plant == x[i],]
png(paste(x[i], "_plot", ".png", sep = ""), width = 450, height = 450)
plot(y$conc, y$uptake, type = "b", col = "red", main = paste(x[i], "plot and blaa", sep = " - "))
dev.off()
}


# Write files


df <- data.frame(CO2)
x <- levels(df$Plant)


for(i in 1:length(x)){
y <- df[df$Plant == x[i],]
write.table(y, paste(x[i], "_data", ".txt", sep = ""), sep = "\t", row.names = F) 
}


# Read several files and append them to a data frame (the same can be done for a vector, but use append() command)


path <- getwd() # You can change this as you will, remember to use / instead of \ in the file path
files <- dir(path, pattern = "_data.txt")


df <- data.frame()
for(i in 1:length(files)){
x <- read.delim(files[i])
df <- rbind(df, x)
}

And a lot more. You can also make loops inside loops. While making these loops a good tip is to start with

i <- 1

for instance. Then you can write the script with "i" already on it's place. Test it. If it works, add the for(){} command. If not, you'll still have time to fix it without crashing your computer (this can happen, if you make a mistake, so save your files frequently).

Read more...

Sunday, April 3, 2011

Photo of the Day - Black-Winged Stilt


Read more...

Thursday, March 3, 2011

Photo of the Day - In a Fish Bowl


Read more...

Wednesday, November 3, 2010

R tips - How to calculate diet indices from time-series data?

Ok, since I am supposed to write also about my work here, I'll start a new series called "R tips". R is an open source statistical program useful especially for nature scientists. This might be very nerdy and useless "shait" for the most, but I hope that some lucky Googlers find these tips useful. At least I have found this kind of blog entries very helpful when doing my work.

Lately I have been working with a seabird diet time-series. I have learned that there are tens of different indices that can be used to describe the dataset. Best fitting index has to be chosen individually depending on the questions and data. Swanson & Krapu (1974) made a review of the issue. Here I am going to demonstrate how to calculate "frequency of occurrence", "aggregate mass", "aggregate percentage" and mean mass for a time-series.

Shortly, frequency of occurrence tells how frequently a diet item occurs in the dataset. The aggregate mass tells the percentage for a diet item of summed total volume of all samples. Finally, the mean of mass percentages, or aggregate percentage, tells the average over the dataset of how many percentages a diet item constitutes of a stomach sample. This is much better explained in Swanson & Krapu 1974.

There are of course thousands of ways to do this, but simplest I have found so far is by using "reshape" package. Here is the R code:

#Assume a dataset where "a", "b" and "c" are diet items, "x1", "x2" ... are diet samples from individual birds and "y1" and "y2" are different years. Values for diet items are given in grams:

a <- c(1, 1, 2, 0, 3, 0, 5, 6, 1, 2)
b <- c(2, 1, 3, 2, 5, 2, 3, 5, 1, 0)
c <- c(0, 0, 1, 2, 4, 0, 20, 0, 0, 0)
year <- c(rep("y1", 5), rep("y2", 5))
bird <- paste(rep("x", 10), seq(1,10,1), sep="")

data <- cbind.data.frame(bird, year, a, b, c)

library(reshape)  # start the reshape package

data$total.mass <- rowSums(data[3:5]) # create total.mass column for later use
melt.data <- melt(data, id=1:2, measured=3:6) # melt the data so that we can cast it in desired format

# start from easiest, mean mass and standard deviation.

t(cast(melt.data, formula = year ~ variable, mean)) #Transposing t() because it is better to list diet items as rows when there are a lot of prey items
t(cast(melt.data, formula = year ~ variable, sd))

# aggregate mass needs column sum and total mass for each year

mass.sum <- cast(melt.data, formula = year ~ variable, sum)
aggregate.mass <- (mass.sum[2:5]/mass.sum$total.mass)*100

#if you want to print the dataframe, you can do following:

rownames(aggregate.mass) <- levels(mass.sum$year)
print(t(aggregate.mass), digits = 1)

#aggregate percentage

data.per <- cbind.data.frame(data[1:2], (data[3:6]/data$total.mass)*100) # calculate how big percentage each diet item consitutes in each sample
data.per <- data.per[-6] # drop off useless total.mass column
melt.data.per <- melt(data.per, id=1:2, measured=3:5)
aggregate.percentage <- cast(melt.data.per, formula = year ~ variable, mean)

#frequency of occurrence

data.na <- data
data.na[data.na==0] <- NA
melt.data.na <- melt(data.na, id=1:2, measured=3:6, na.rm = T)
occur <- cast(melt.data.na, formula = year ~ variable, length)
t(cbind.data.frame(occur[2:4]/occur$total.mass, row.names = levels(occur$year)))

#comparison between aggregate percentage and aggregate mass

rownames(aggregate.percentage) <- levels(aggregate.percentage$year)
aggregate.percentage <- aggregate.percentage[-1]
aggregate.mass <- aggregate.mass[-4]

aggregate.percentage-aggregate.mass

# differences are mainly because of 20 grams of item c in bird x7. The aggregate volume method gives equal weight to each unit of food consumed by any bird while the aggregate percent method gives equal weight in the analysis to each bird as Swanson & Krapu (1974) says.

Please tell, if there are mistakes in scripts.

References

Swanson, G. A., G. L. Krapu, et al. (1974). "Advantages in Mathematically Weighting Waterfowl Food-Habits Data." Journal of Wildlife Management 38(2): 302-307.

Read more...

Friday, September 24, 2010

Photos from the field season 2010



All my albums in Picasa are finally updated with fresh photos from field season 2010. You can check them out here.

Read more...

Thursday, September 23, 2010

Forskningsdagene


Forskningsdagene is a popular scientific event arranged once a year in Norway. The idea is that institutions are presenting their research for interested public. I think this is a great idea, since the public is often funding our research. Only problem with the event is that the "big names" are not having time to talk to the mortals. The task is often given for younger people. Well, on the other hand it's great fun for us and maybe we are as able to show scallops for kids as any experienced researcher...

This was my second year with Forskningsdagene. My input for popular science this year was to take part for a cruise to Senjahopen with the University's research vessel Johan Ruud. This was also my first time, and probably the last for a long time, as a cruise leader. We went to show marine organisms for school kids on Senja. The science was not that interesting after all, but they found it incredibly entertaining when a sea cucumber was "pissing" on their pants...
Tomorrow we will anchor the boat to the harbour by Stortorget. The show starts at 11 o'clock. Come to check out where the sea cucumber pisses...

Read more...

Wednesday, September 22, 2010

No Health-Care for a Beaten Bird

In nature unexpected events follow each other. Many times observing nature is possible only, when you manage to forget observing yourself. Patience is the number one gift of a nature observer.
Guillemots seem to be a bird-world equivalent to people from India. The huge density of breeding colonies forces the birds to give an impression of compliant sitting next to each other, but real life in the colonies is often unlike the impression. Fights do occur. Fighting starts with slight pecking and sometimes develops into a serious attempt of murder. Most serious matches are solved in the air and finally end up into the ocean, where the weaker party is trying to escape by diving, flying, swimming and splashing from the murderous rage of the strong.
Sometimes Brünnich’s guillemots are bleeding after fighting, but I have never before seen any serious damage due to these fights. When counting birds in vicinity of tens of thousands of guillemots, probability of seeing rare occasions is higher. This combatant lost his fight and came to look for refuge from us, while swarming glaucous gulls were waiting to attack the beaten bird. There was not much we could do, except for taking photos. Finally we had to leave and the bird ended up as a meal for the hungry glaucous gulls. To live is to die. 

Read more...

Friday, August 27, 2010

A Bivalve Challenge



Some words about my work this time. As said, I am working with marine bivalves. The first and foremost challenge in the PhD student life, compared to my former jobs, is the freedom. Ok, I have supervisors, who are trying to keep me on the right path, but still there are so many ways to go. Asking me "what are you exactly working with?" is a bad idea. I hardly know it myself. Projects are numerous. Maybe some of them gives results in the end.
Lisää kuvateksti

Right now I am trying to find out the most effective ways to take samples. Since I need quantitative (=sampled area of seafloor is known) samples for bivalve population study, I have been experimenting with an under-water suction pump. Playing with the pump is turning out to a success and I even got my first useful sample. With the sample became another challenge: which species are these guys? Unlike with crustaceans, there is no really descriptive literature on mollusc shells. One just have to ask around and look for photos on the internet and in old books.


Lisää kuvateksti
In addition I am writing a funding application to study growth band formation in bivalve shells. These growth bands can be used as archives to study past climate and the variability of conditions between sites. First we have to find out in what kind of conditions various elements and isotopes are deposited into the shells...
Lisää kuvateksti

Read more...

Thursday, August 26, 2010

A fishless fishing trip to Senja

Sunset somewhere at the "yttersida" of Senja.
Should not write only about Svalbard all the time. So here comes something quick about my free time activities. Senja is the next island south from Kvaløya. It offers almost everything for outdoor activities all the way from climbing to hunting, fishing or diving. Last weekend we went for a fishing trip to some lakes in the mountains on the island. The trip did not offer that much fish, but great time in the nature anyhow. On the way back we stopped for a dive. Visibility was not that great, but the site is amongst the best I have been diving around here.

Mytilus (blue mussels) collected under the wharf were not poisonous after all, although you shouldn't eat those from the inner coast at this time of the year. These bivalves are filter-feeders and may accumulate algae toxins, which can contain some fairly serious stuff. The bivalves were collected close to the open ocean and the risk to get sick is fairly low. It's called exiting eating, like fugu, either you brag that you survived or then you'll die.

Mefjordbotn, one of the most spectacular nature diving sites in the area

Read more...

Wednesday, August 25, 2010

Photo of the Day - The Isle of Hope

Hopen (eng. The Isle of Hope) is one of those miserable islands surrounded by a cold ocean. During summer sunny hours on the island can be counted with fingers of one hand and the record of continuous fog is about three months. Considering these facts, we were quite lucky to see the island at all, although we spent a week anchored next to it.

Read more...

Tuesday, August 24, 2010

Photo of the Day - Great Skua


The great skua is "the predator" of Svalbard bird life. In addition to bird chicks and eggs their diet consists of adult birds, such as kittiwakes, eiders and little auks. The eagle like look is not a coincidence... 

Read more...

Wednesday, August 18, 2010

Photo of the Day - "Who's your Daddy?"

Feet of new-born bird chicks are those that grow first. This grey phalarope chick was catching small insects with its father, while the mother was keeping some distance.

Read more...

Tuesday, August 17, 2010

Photo of the Day - A Finwhale Nose

Fin whales are the second largest animals on the Earth. This individual was almost the length of our sailing boat (49 ft). It is an exiting sight when this huge animal dives under your boat. You never know where it comes up...

Read more...

Monday, August 16, 2010

Photo of the Day - Descended from Reptiles

Have you ever wondered why they say that birds are evolved from reptiles? Well, this Arctic skua has some dinosaur-look, doesn't it?

Read more...

Saturday, August 14, 2010

Photo of the Day - Almost Brave

Walruses are curious animals. If you are sitting still in a boat, they may come pretty close, but get also scared very easily. Here a group of young males (as long as I can say) is getting scared - once again - while trying to check us out.

Read more...

Friday, August 13, 2010

Photo of the Day - Black Guillemots in Mist

Black guillemots are difficult to photograph, because of their almost pure black and white plumage. Sometimes in right conditions it is possible to get the feathers visible. This one was taken in mist, while sun was shining partly through the clouds. 

Read more...

Thursday, August 12, 2010

Photo of the Day - And So It Dives...Again

Here is an other piece of evidence: polar bears are - indeed - marine mammals. There were six polar bears diving for rotten blubber. Most of the whale (probably a fin whale) was already eaten, although some blubber was left at the deepest (about 3-4 meters) parts of the whale. This dive was a success. The polar bear came up with a junk of rotten whale blubber.  

Read more...

Wednesday, August 11, 2010

Photo of the Day - Nordaustlandet

Read more...

Tuesday, August 10, 2010

Photo of the Day - Bear Posing

Getting good photos of polar bears may be tricky sometimes, since it is not actively allowed to search for them. Very often they get scared of people and following them is about the worst thing one can do. On Storøya, east of Nordaustlandet, things were different. While counting birds we counted 13 polar bears on the island. Most of the encounters were like this one. Due to our silent 4-stroke engine, the polar bears did not hear us coming while taking it easy somewhere between rocks. We on our behalf spotted them while trying to go on land to count birds. A few times we had to return back to our boat or turn back just when trying to go on land, because of curious individuals...then we were just staring and examining each other. It is difficult to tell which one, us or the bear, was more facinated about the behaviour of the other. 

Read more...

Monday, August 9, 2010

Faceshow!

 
Comment something poor in your status, add me as a friend, join into my stupid group and I'll jump out from a window, try posting most embracing photos of your friends - especially if they are in a state that they cannot remember next morning or just play a Jesus and join a cause to save the world.
 
In the modern world possibilities to lose your face on the internet are almost endless - partly thanks to Facebook.
 
Therefore this Walrus Faceshow (TM) is dedicated to the slaves of the Devils invention. You hate it, but yet you are a slave of it - you never know, if someone actually had something important to tell...this haven't happened yet, but maybe tomorrow?

 
 Try to give this your friends name. He won't like it, but can' really remove it either, because this would show bad sense of humour. Very funny trick, isn't it? 

The Drowsyhead and The Madeye - eyes red as in a bad hangover. Gaze as hateful as if he would like to eat you. Still a relaxed and funny fellow. Often looks are difficult to interpret.
 
  Surprised how personal walrus faces can look? Me too. Here I photographed six different animals. Guess who is photographed more than once...
 
Wildlife photography is a great hobby. This photography session was something I will remember for a long time. All you needed to do was to stand on the shore and whistle - they came to you. Walruses are very curious animals.
 

Read more...