Во вчерашнем посте Аналитика в дистанционном обучении (кейс для работы) основная идея аналитики - посмотреть, какие факторы влияют на оценку курса обучаемым.
Однако в самой оценке курса могут быть проблемы: кто-то подходит серьезно, ставя оценки взвешенно, кто-то "лепит" подряд "пятерки", кто-то всегда "троечки".
В нашем кейсе (прикрепленные данные) 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 - еще несколько классных вариантов решения
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())->
require(data.table)
dt= data.table(your.data.frame)
result= dt[, list(userId, score= mean(score, na.rm=T)), by=userId]
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,
Однако в самой оценке курса могут быть проблемы: кто-то подходит серьезно, ставя оценки взвешенно, кто-то "лепит" подряд "пятерки", кто-то всегда "троечки".
В нашем кейсе (прикрепленные данные) 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 dplyrlibrary('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,
Какая крутая штука!
ОтветитьУдалить