2015-09-24 1 views
3

Сегодня я нашел проблему, которую я не могу объяснить. Это хорошо известное поведение?sqldf меняет числовой столбец на символ один, когда его заказывают

Dataset:

structure(list(Original.Unit = c("some unit", "some unit", "some unit", 
"some unit", "some unit", "some unit"), Result = c(24, 28, NA, 
4.1, 4.5, 2.6), Conversion.Factor = c(1, 1.54, 1, 2.2, 1, 1)), .Names = c("Original.Unit", 
"Result", "Conversion.Factor"), row.names = c(NA, 6L), class = "data.frame") 

Код:

> require(sqldf) 

> (data <- dget("file")) # "file" contains the above structure 
    Original.Unit Result Conversion.Factor 
1  some unit 24.0    1.00 
2  some unit 28.0    1.54 
3  some unit  NA    1.00 
4  some unit 4.1    2.20 
5  some unit 4.5    1.00 
6  some unit 2.6    1.00 

> sapply(data, function(d) { class(d)}) 
    Original.Unit   Result Conversion.Factor 
     "character"   "numeric"   "numeric" 

Давайте запрос так:

> (result <- sqldf("SELECT `Original.Unit`, Result, `Conversion.Factor`, Result * `Conversion.Factor` AS ConvResult FROM data")) 
    Original.Unit Result Conversion.Factor ConvResult 
1  some unit 24.0    1.00  24.00 
2  some unit 28.0    1.54  43.12 
3  some unit  NA    1.00   NA 
4  some unit 4.1    2.20  9.02 
5  some unit 4.5    1.00  4.50 
6  some unit 2.6    1.00  2.60 

> sapply(result, function(r) { class(r)}) 
    Original.Unit   Result Conversion.Factor  ConvResult 
     "character"   "numeric"   "numeric"   "numeric" 

Насколько хорошо. Теперь давайте разберёмся результат в последней колонке:

> (result <- sqldf("SELECT `Original.Unit`, Result, `Conversion.Factor`, Result * `Conversion.Factor` AS ConvResult FROM data ORDER BY ConvResult")) 
    Original.Unit Result Conversion.Factor ConvResult 
1  some unit  NA    1.00  <NA> 
2  some unit 2.6    1.00  2.6 
3  some unit 4.5    1.00  4.5 
4  some unit 4.1    2.20  9.02 
5  some unit 24.0    1.00  24.0 
6  some unit 28.0    1.54  43.12 

И посмотреть на типы:

> sapply(result, function(r) { class(r)}) 
    Original.Unit   Result Conversion.Factor  ConvResult 
     "character"   "numeric"   "numeric"  "character" 

Почему колонка ConvResult теперь типа персонажа? Это из-за НС?

Кажется, что это пункт. Когда я заменил NA, скажем, 1000, ConvResult стал числовым. Но почему это происходит?

+0

Обходной путь, закажите результат за пределами sqldf. 'result <- result [order (result $ ConvResult),]' – zx8754

+2

SQLite использует первую строку для получения информации о типе, и в этом случае первая строка 'ConvResult' является NA, поэтому она не может сказать. Вы можете попробовать свой запрос, используя бэкэнд H2: 'library (RH2); sqldf ("...") ' –

ответ

3

Да, кажется, вы правы. При использовании ORDER BY sqldf склоняется к угадыванию класса выходного столбца, и в этом случае он делает ошибку. Поэтому, я думаю, вы могли бы сами задать типы столбцов:

result <- sqldf("SELECT `Original.Unit`, Result, `Conversion.Factor`, Result * `Conversion.Factor` AS ConvResult FROM data ORDER BY ConvResult",method = c("character", "numeric", "numeric", "numeric")) 
+0

Спасибо за объяснение! sqldf предоставляет еще больше проблем. Он теряет кодировку (или, скорее, кодирует литералы из UTF8 в локальную кодировку), иногда теряет класс POSIXct и многое другое. Но я все равно люблю :) Так как я создал функцию sqldfEx, которая «обертывает» sqldf и сразу исправляет многие «проблемы», я обновлю ее с помощью этого. Благодаря! – Bastian