I have a dataset that contains the feeding data of 3 animals, consisting of the animals' tag ids (1,2,3), the type (A,B) and amount (kg) of feed given at each 'meal':

Animal   FeedType   Amount(kg)
Animal1     A         10
Animal2     B         7
Animal3     A         4
Animal2     A         2
Animal1     B         5
Animal2     B         6
Animal3     A         2

Using this, I want to be able to output the matrix below which has unique('Animal') as its rows, unique('FeedType') as its columns and the cumulative Feed Amount (kg) in the corresponding cells of the matrix.

         A   B
Animal1  10  5
Animal2  2   13
Animal3  6   0

I started coding a solution using two for loops as below:

dataframe = read_delim(input_url, header=TRUE, sep = ";")
animal_feed_matrix = matrix(0,nrow(unique('Animal')),nrow(unique('FeedType')))
for (i in 1:length(unique('Animal')) ){
 a= unique('Animal')[i]
  for (j in 1:length(unique('FeedType')) ){
    ft= unique('FeedType')[j]
    animal_feed_matrix[i,j] = sum(dataframe [(dataframe ['Animal']==a & dataframe ['FeedType']==ft),'Amount(kg)'])
  }
}

But I am aware that this is a very inefficient way to tackle the problem, (plus the code above needs to be completed in order to work). I am aware that R has levels, and factors, which I sense can solve the problem more elegantly.

P.S: This question is somewhat similar to mine but even if the solution to my problem is contained within, it escapes me.

有帮助吗?

解决方案

In base R:

out <- with(mydf, tapply(Amount, list(Animal, FeedType), sum))

         A  B
Animal1 10  5
Animal2  2 13
Animal3  6 NA

Then, to change NA to 0 (as in your example), just do:

out[is.na(out)] <- 0

其他提示

You can do it with function dcast() from library reshape2.

library(reshape2)    
dcast(df,Animal~FeedType,sum,value.var="Amount")
   Animal  A  B
1 Animal1 10  5
2 Animal2  2 13
3 Animal3  6  0
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top