Как извлечь коды из фактора

Прежде всего, я хотел бы заранее извиниться, если я не буду очень ясен в своем вопросе. Я совершенно новичок в R, и моя терминология не будет такой хорошей.

Мы получаем файл SPSS от внешней компании, который содержит данные опроса. У нас есть R-скрипт для извлечения данных и записи их в CSV-файл. Это прекрасно работает.

Вторая часть скрипта создает файл в стиле INI для всех возможных ответов. Например, для AGE у нас будет что-то вроде

[ AGE ]
1 = Under 13
2 = 13 - 15
3 = 15 - 25
4 = 25+

Файл CSV будет иметь одну из 1, 2, 3 или 4 для каждой строки. До недавнего времени все возможные ответы нумеровались с 1, а теперь некоторые из них начинаются с 0. Поэтому хотелось бы иметь что-то вроде:

[ AGE ]
0 = Under 13
1 = 13 - 15
2 = 15 - 25
3 = 25+

Ниже приведен текущий код R, который мы используем. Я знаю, где что-то не так, но я не знаю, как это исправить.

data<-read.spss(inputFile, to.data.frame=TRUE);
fileOut<- file(valuesExportFile, "w");
for (name in names(data)) {
  cat("[", name,"]\n", file=fileOut);
  variableValues<-levels(data[[name]]);
  numberOfValues<-nlevels(data[[name]]);
  if (numberOfValues > 0) {
     for (i in 1:numberOfValues) {
         cat(i, '= "', variableValues[i], '"', "\n", file=fileOut);
     }
  }
};
close(fileOut);

Я потратил полтора дня на гугление и пробовал разные подходы. Я нашел perl-скрипт spssread.pl, который извлекает данные так, как нам нужно, но по какой-то причине все имена меток в верхнем регистре, что неприемлемо, поскольку они чувствительны к регистру. Я буду продолжать смотреть на этот скрипт, а пока я хотел бы посмотреть, есть ли решение с использованием R, так как это то, что мы уже используем, и было бы неплохо иметь все в одном скрипте.

Итак, есть предложения?


person giuliot    schedule 30.04.2012    source источник
comment
Просто мысль: cat(i-1,...)?   -  person joran    schedule 30.04.2012
comment
...где и как тогда что-то пойдет не так? Это просто -1, который предложил @joran, или есть другие проблемы?   -  person Tommy    schedule 30.04.2012
comment
Я не могу просто использовать cat(i-1,...), потому что некоторые начинаются с 1, а некоторые начинаются с 0. Если я открою файл данных с помощью PSPP и посмотрю на вкладку Variable View, я увижу, что значения упорядочены правильно, некоторые начинаются с 0, а некоторые начинаются с 0. с 1. Так что я думаю, должен быть способ извлечь эту информацию из файла SPSS.   -  person giuliot    schedule 01.05.2012
comment
Вы смотрели на структуру данных, которую вы получите, если не включите аргумент as.data.frame=TRUE в read.spss? Согласно странице справки, есть атрибут label.table, который содержит (возможно, больше) информации о метках значений, чем то, что содержит data.frame.   -  person Brian Diggs    schedule 01.05.2012
comment
Спасибо, Брайан. Хотя то, что вы предложили, используя label.table, не сработало, это как бы направило меня в правильном направлении.   -  person giuliot    schedule 02.05.2012


Ответы (1)


Благодаря Брайану Диггсу я смог исследовать другой путь и нашел решение, хотя и не идеальное.

Мое решение состояло в том, чтобы извлечь данные с помощью use.value.labels=FALSE, а затем отменить класс переменной и использовать атрибут value.labels. Я думаю, что показать код было бы понятнее, чем пытаться его объяснить.

data<-read.spss(inputFile, to.data.frame=TRUE, use.value.labels=FALSE);
fileOut<- file(valuesExportFile, "w");
for (name in names(data)) {
    cat("[", name,"]\n", file=fileOut);
    variables<-attr(unclass(data[[name]]), "value.labels");
    for (label in names(variables)) {
        cat(variables[[label]], '= "', label, '"', "\n", file=fileOut);
    }
};
close(fileOut);

Результат

[ AGE ]
8 = " 65+ "
7 = " 55 to 64 "
6 = " 45 to 54 "
5 = " 35 to 44 "
4 = " 25 to 34 "
3 = " 21 to 24 "
2 = " 16 to 20 "
1 = " 13 to 15 "
0 = " Under 13 "

хоть и рабочий, но не идеальный. Кто-нибудь знает, как я могу отсортировать их так, чтобы

[ AGE ]
0 = " Under 13 "
1 = " 13 to 15 "
2 = " 16 to 20 "
3 = " 21 to 24 "
4 = " 25 to 34 "
5 = " 35 to 44 "
6 = " 45 to 54 "
7 = " 55 to 64 "
8 = " 65+ "

РЕДАКТИРОВАТЬ: 05.04.12

После дополнительной помощи Брайана Диггса (см. комментарии) окончательные решения

data<-read.spss(inputFile, to.data.frame=TRUE, use.value.labels=FALSE);
fileOut<- file(valuesExportFile, "w");
for (name in names(data)) {
    cat("[", name,"]\n", file=fileOut);
    variables<-attr(unclass(data[[name]]), "value.labels");
    variables<-variables[order(as.numeric(variables))];
    for (label in names(variables)) {
        cat(variables[[label]], '= "', label, '"', "\n", file=fileOut);
    }
};
close(fileOut);
person giuliot    schedule 02.05.2012
comment
Может быть, перед циклом for добавить variables <- sort(variables)? Непроверенный. Идея состоит в том, чтобы получить variables в правильном порядке, чтобы, когда вы перебираете его, он печатался в том порядке, в котором вы хотите. - person Brian Diggs; 02.05.2012
comment
Спасибо, Брайан. Он отлично работает, если у меня меньше 10 элементов. Я думаю, что порядок не численный, и поэтому 10 предшествует 2. - person giuliot; 03.05.2012
comment
Да, это лексическая сортировка, а не числовая. Попробуйте variables <- variables[order(as.numeric(variables))] Это получает порядок сортировки из числовой версии variables, а не строковой версии. - person Brian Diggs; 03.05.2012