.

Сделать репост в соц сети!

вторник, 13 января 2015 г.

Vlookup (ВПР) в Rstudio



Во вчерашнем посте Аналитика в дистанционном обучении (кейс для работы) основная идея аналитики - посмотреть, какие факторы влияют на оценку курса обучаемым.
Однако в самой оценке курса могут быть проблемы: кто-то подходит серьезно, ставя оценки взвешенно, кто-то "лепит" подряд "пятерки", кто-то всегда "троечки".
В нашем кейсе (прикрепленные данные) 36 000 строк - записей о прохождении курсов и 4 900 юзеров или работников компании, т.е. на каждого работника примерно 7 курсов.
на самом деле статистика такая
  Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  1.000   2.000   5.000   6.838  10.000  39.000
a = table(r$ID)
b = as.data.frame(a)
summary(b$Freq)

.....
У нас может стать задача брать в качестве зависимой переменной не абсолютную оценку учащегося, а относительную его оценку (например оценку по данному курсу делим на среднее его оценок по всем пройденным курсам). Или нам нужно удалить из анализа всех, у кого дисперсия оценки равна 0 (т.е. учащийся всегда ставил одну оценку, и мы подозреваем, что такие оценки только засоряют анализ).
Для этого мы применяем функцию ave
r$p = ave(r$ocenka, r$ID, FUN = mean)
если среднее. И тогда создаем новую переменную
r$p1 = r$ocenka / r$p
или
r$p = ave(r$ocenka, r$ID, FUN = sd)
исключаем всех, кто прошел 1-2 курса (ну смешно искать дисперсию по одной оценке), далее выкидываем тех, кто оценивал все курсы на одну оценку и считаем уже регрессию)
вот здесь vlookup for Rstudio - еще несколько классных вариантов решения

Первый

If you have a data frame. I would get used to using dplyr 

library('dplyr') 

# create some fake data for demonstration 
x <- 100="" data.frame="" replace="T), </span" sessionid="sample(1:10,">
userID = sample(letters[1:10], 100, replace=T), 
scores = rnorm(100)) 

# mean scores by userID 
x.df <- group_by="" userid="" x="">% 
summarize(mean.score = mean(scores, na.rm=T), count = n()) 

# mean scores by userID and sessionID 
x.df <- group_by="" sessionid="" userid="" x="">% 
summarize(mean.score = mean(scores, na.rm=T), count = n())





Еще

Aggregations with data.table's works a lot faster than data.frame's: 
require(data.table) 
dt= data.table(your.data.frame) 
result= dt[, list(userId, score= mean(score, na.rm=T)), by=userId]


Еще

Combining Jesse and Alex's examples: 

library('data.table') 

# create some fake data for demonstration 
x <- 100="" data.frame="" replace="T), </span" sessionid="sample(1:10,">
userID = sample(letters[1:10], 100, replace=T), 
scores = rnorm(100)) 

#convert x to a data.table 
y <- data.table="" nbsp="" span="" x="">

#calculate the mean of scores by userID, calling this column "userSessionAvg" 
z <- list="" na.rm="T)),by=userID] </span" usersessionavg="mean(scores," y="">

#merge the two on userID (should use merge.data.table, faster than merge.data.frame) 
a <- merge="" span="" y="" z="">


Лучший 

these solutions are a bit heavy. dplyr and data.table are definitely worth using, but are not really necessary here. if d is your data.frame: 

d$meanscores <- d="" dim="" nbsp="" rep="" span="">
for (uid in unique(d$userID)) {widx <- d="" mean="" meanscores="" nbsp="" scores="" span="" userid="=uid);" which="" widx="">

you can check by doing sum(is.na(d$meanscores)) which should be zero.

программа R, 

1 комментарий: