2013-09-17 4 views
1

Im имея некоторые проблемы строит функцию (или с помощью некоторых применить шикарно) в R. У меня есть набор данных, как это:R Выполнение вычислений общего

df<- data.frame(id <-sample(1:10,100, replace = T), 
price <-runif(20)*100, 
q = sample(1:100,100, replace = T)) 
colnames(df)<-c("id","price","quantity") 

Теперь мне нужно, чтобы рассчитать среднюю цену для каждого человека Я БЫ. Так что я могу сделать это с помощью каждого отдельного идентификатора, как это:

sum(((df$p[df$id == "1" ])*(df$q[df$id == "1" ])/(sum(df$q[df$id == "1" ])))) 

Но как мне сделать это пройти через все возможные значения ФР $ ид и распечатать его в виде матрицы/DF, который также содержит идентификатор наряду с сумма? У меня около 6000 разных идентификаторов и около 180000 об. так что было бы неплохо, если бы это было также возможно сделать это быстро?

разбив его по-другому, пусть это мои данные:

id price quantity 
1 10 2 
1 20 1 
1 50 5 
2 5  5 
2 3  6 
2 10 4 

Так вот решение для ID = 1 будет: (10 * 2 + 20*1 +50 * 5)/(2+1+5) = 36.25 Это дает мне цену пр. устройство для всех устройств с ID = 1.

Обновлено, используя set.seed(1234) и это datageneration:

set.seed(1234) 
df<- data.frame(id <-sample(1:10,100, replace = T), 
price <-runif(20)*100, 
q = sample(1:100,100, replace = T)) 
colnames(df)<-c("id","price","quantity") 

Результаты должны выглядеть следующим образом:

id avg.price.per.unit 
1 33,71 
2 29,84 
3 44,53 
4 36,27 
5 69,63 
6 35,99 
7 45,26 
8 58,32 
9 33,36 
10 9,67 

Округление может быть поодаль ,

+0

Я добавил «Ломая», так как предыдущее решение от Manetheran принимает очень много времени для запуска. – NoThanks

ответ

2

Пробуйте использовать ddply из библиотеки plyr. [EDIT] Теперь, когда плакат (наконец) определил для нас точный расчет, который он/она хочет, решение прост.

set.seed(1234) 
df<- data.frame(id <-sample(1:10,100, replace = T), 
price <-runif(20)*100, 
q = sample(1:100,100, replace = T)) 
colnames(df)<-c("id","price","quantity") 

library(plyr) 

df2 <- ddply(df, .(id), summarise, 
      price.x.quantity = sum(price*quantity), 
      sum.q = sum(quantity)) 
df2$avg <- with(df2, price.x.quantity/sum.q) 
df2 

Что дает это:

> df2 
    id price.x.quantity sum.q  avg 
1 1  17668.111 524 33.717769 
2 2  18559.773 622 29.838863 
3 3  35222.731 791 44.529369 
4 4  28433.181 784 36.266813 
5 5  10304.568 148 69.625462 
6 6  31534.830 876 35.998665 
7 7  29513.494 652 45.266095 
8 8  25542.908 438 58.317141 
9 9  22216.174 666 33.357619 
10 10   2263.581 234 9.673423 
> 
+0

Это дает мне среднюю цену (только по цене). Im ищет среднюю цену pr. количество. Соответствующая функция находится в df2 <- ddply (df,. (Id), суммировать, avg.price = ЗДЕСЬ) im возникают проблемы с? – NoThanks

2

Вы можете использовать функцию во всех ваших уникальных идентификаторов:

avgPrices <- sapply(unique(df$id), function(i) { 
    sum(((df$p[df$id == i ])*(df$q[df$id == i ])/(sum(df$q[df$id == i ])))) 
}) 
result <- cbind(unique(df$id), avgPrices) 
colnames(result) <- c("id", "avg.price") 

Или более просто используя plyr пакет:

library(plyr) 
ddply(df, .(id), summarize, avg.price=sum(price/quantity)) 

Или в качестве альтернативы можно взять SQL подход:

library(sqldf) 
sqldf("SELECT id, sum(price/quantity) AS 'avg.price' FROM df GROUP BY id") 
+0

У меня возникли проблемы с получением вашего первого решения, которое, я думаю, является тем, что я ищу. Я хочу получить сумму (p_ij * q_ij + p_ik * q_ik + ...)/sum (q_ij + qik + ...) для каждого идентификатора. Насколько я вижу, plyr этого не делает. – NoThanks

+0

Можете ли вы сделать это с помощью первого метода ('sapply') или настроить там расчет? Я немного смущен, что ваши «j» и «k» будут в этой ситуации. –

+0

Сладкий, получил ваш первый пример для работы, просто отсутствует парантеза после} – NoThanks

Смежные вопросы