Используя пакет data.table, который доставит самое быстрое время пользователя? (Программирование R) - PullRequest
1 голос
/ 27 февраля 2020

У меня был этот вопрос на тесте в онлайн-тренинге. Я понял это правильно методом проб и ошибок. Скорее всего, я делаю что-то не так, потому что я новичок в программировании на R.

Это вопрос:

question image

До Вы читаете мой код R, обратите внимание, что для последней части мне пришлось преобразовать все столбцы в цифру c, потому что без этого я получал следующее сообщение:

"Ошибка в rowMeans ( DT): 'x' должно быть цифрой c. "

В тесте мое решение профессора:" DT [, среднее (pwgtp15), = SEX ] "

С моим кодом R правильный ответ будет среднее (DT $ pwgtp15, = DT $ SEX) .

Я получаю этот вывод:

Output Image

Я сомневаюсь, что, возможно, мой способ заставить работать DT [, значит (pwgtp15), = SEX] производит медленные вычисления.

Для этого я использовал

DT <- data.frame(data.matrix(DT))

Какой из них правильный ответ? Профессор решение? Мой ответ? Еще один?

Вот мой код:

#THE SOLUTION IS DT[,mean(pwgtp15), by=SEX]
#HOWEVER, my solution is mean(DT$pwgtp15, by=DT$SEX)

install.packages("data.table")

library("data.table")

# the example below runs 100 times
download.file("https://d396qusza40orc.cloudfront.net/getdata%2Fdata%2Fss06pid.csv", destfile = "ACS.csv")

DT <- fread("ACS.csv", sep = ",")



counter<- 0
myName<-"DT[,mean(pwgtp15), by=SEX]"
for (i in 1:100)
{
  a<- Sys.time()  
  DT[,mean(pwgtp15), by=SEX]
  b<-Sys.time()
  myTime<-b-a
  counter<- counter + myTime
}
cat("counter is: ", counter, "myName is: ", myName, "\n")



counter<- 0
myName<-"mean(DT[DT$SEX==1,]$pwgtp15);mean(DT[DT$SEX==2,]$pwgtp15)"
for (i in 1:100)
{
  a<- Sys.time()  
  mean(DT[DT$SEX==1,]$pwgtp15); mean(DT[DT$SEX==2,]$pwgtp15)
  b<-Sys.time()
  myTime<-b-a
  counter<- counter + myTime
}
cat("counter is: ", counter, "myName is: ", myName, "\n")



counter<- 0
myName<-"sapply(split(DT$pwgtp15,DT$SEX),mean)"
for (i in 1:100)
{
  a<- Sys.time()  
  sapply(split(DT$pwgtp15,DT$SEX),mean)
  b<-Sys.time()
  myTime<-b-a
  counter<- counter + myTime
}
cat("counter is: ", counter, "myName is: ", myName, "\n")



counter<- 0
myName<-"tapply(DT$pwgtp15, DT$SEX, mean)"
for (i in 1:100)
{
  a<- Sys.time()  
  tapply(DT$pwgtp15, DT$SEX, mean)
  b<-Sys.time()
  myTime<-b-a
  counter<- counter + myTime
}
cat("counter is: ", counter, "myName is: ", myName, "\n")



counter<- 0
myName<-"mean(DT$pwgtp15, by=DT$SEX)"
for (i in 1:100)
{
  a<- Sys.time()  
  mean(DT$pwgtp15, by=DT$SEX)
  b<-Sys.time()
  myTime<- b-a
  counter<- counter + myTime
}
cat("counter is: ", counter, "myName is: ", myName, "\n")



#We convert the entire DATAFRAME to numeric
#Otherwise rowmeans will not work
DT <- data.frame(data.matrix(DT))


counter<- 0
myName<-"rowMeans(DT)[DT$SEX==1];rowMeans(DT)[DT$SEX==2]"

for (i in 1:100)
{
  a<- Sys.time()  
  rowMeans(DT)[DT$SEX==1];rowMeans(DT)[DT$SEX==2]
  b<-Sys.time()
  myTime<- b-a
  counter<- counter + myTime
}
cat("counter is: ", counter, "myName is: ", myName, "\n")

1 Ответ

1 голос
/ 27 февраля 2020

Как уже говорилось, выбор ответа на вопрос не дает одинаковых результатов. Не существует именованного параметра от до до base::mean(). Поскольку функция допускает дальнейшие аргументы, передаваемые в или из других методов , она не выдает ошибку по аргументу. Следовательно, поскольку он не разделяет / поднаставляет такие факторы, как DT$SEX, это будет самое быстрое время.

Кроме того, существуют причины, по которым другие методы возвращаются медленнее:

  • tapply(...), sapply(split(...)), rowMeans(...)

    Все являются прямыми или косвенными применяются члены семейства, которые являются скрытыми циклами и не полностью векторизованными вычислениями , Кроме того, rowMeans является оберткой для apply и вызывается дважды. Плюс, как известно, apply преобразует весь фрейм / таблицу данных в матрицу, где мы должны учитывать @ предостережение Дэвида Аренбурга :

    Если вы работаете с data.frame s, забудьте, что есть функция с именем apply - что бы вы ни делали - не не используйте ее. Особенно с полем 1 (единственный хороший вариант использования этой функции - работать с matrix столбцами - поле 2).

  • mean(...); mean(...)

    Выполняется два вызова для заданных фреймов данных. Логическое индексирование с помощью [ возвращает всех столбцов фрейма данных, затем $ выбирает конечную цифру c столбец для mean().

    На самом деле это будет намного быстрее и, возможно, самый быстрый , если вы запускаете подмножества векторов, а не подмножества фреймов данных, которые возвращают все столбцы:

    mean(DT$pwgtp15[DT$SEX==1]);mean(DT$pwgtp15[DT$SEX==2])
    
    a <- Sys.time() 
    DT[,mean(pwgtp15), by=SEX]
    b <- Sys.time() 
    myTime <- b-a
    myTime
    # Time difference of 0.01888704 secs
    # Time difference of 0.03294992 secs
    # Time difference of 0.03321409 secs
    
    a <- Sys.time() 
    mean(DT$pwgtp15[DT$SEX==1]);mean(DT$pwgtp15[DT$SEX==2])
    b <- Sys.time() 
    myTime <- b-a
    myTime
    # Time difference of 0.006003857 secs
    # Time difference of 0 secs
    # Time difference of 0 secs
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...