Я хотел бы использовать Perl для получения ранее сгенерированного файла синтаксиса SPSS и форматирования его для использования в среде R.Синтаксис Perl Regex
Это, вероятно, очень простая задача для тех, кто знаком с Perl и regex, но я спотыкаюсь.
Шагов, как я изложил их для этого сценария Perl следующим образом:
- Читайте в SPSS файл
- Найти соответствующие куски SPSS файла (регулярные выражения) для дальнейшей обработки и форматирование
- Дальнейшая обработка, отмеченная выше (более регулярное выражение)
- Возврат R синтаксиса к командной строке или предпочтительно к файлу.
Основной формат SPSS синтаксиса значений меток:
...A bunch of nonsense I do not care about...
...
Value Labels
/gender
1 "M"
2 "F"
/purpose
1 "business"
2 "vacation"
3 "tiddlywinks"
execute .
...Resume nonsense...
И желаемый синтаксис R я после выглядит как:
gender <- as.factor(gender
, levels= c(1,2)
, labels= c("M","F")
)
...
Вот сценарий Perl я написал, таким образом, далеко. Я успешно прочитал каждую строку в соответствующем массиве. У меня есть общий поток того, что мне нужно для окончательной функции печати, но мне нужно выяснить, как ТОЛЬКО распечатать соответствующие массивы @levels и @labels для каждого массива @vars.
#!/usr/bin/perl
#Need to change to read from argument in command line
open(VARVAL, "append.txt");
@lines = <VARVAL>;
close(VARVAL);
#Read through each line and put into a variable, a value, or a reject
#I really only want to read in everything between "value labels" and "execute ."
#That probably requires more regex...
foreach (@lines){
if ($_ =~ /\//){ #Anything with a/is a variable, remove the/and push
$_ =~ tr/\///d;
push(@vars, $_)
} elsif ($_ =~/\d/) {
push(@vals, $_) #Anything that has a number in the line is a value
}
}
#Splitting each @vals array into levels or labels arrays
foreach (@vals){
@values = split(/\s+/, $_); #Splitting on a space, vunerable...better to split on first non digit character?
foreach (@values) {
if ($_ =~/\d/){
push(@levels, $_);
} else {
push(@labels, $_)
}
}
}
#Get rid of newline
#I should provavly do this somewhere else?
chomp(@vars);
chomp(@levels);
chomp(@labels);
#Need to tell it when to stop adding in @levels & @labels. While loop? Hash lookup?
#Need to get rid of final comma
#Need to redirect output to a file
foreach (@vars){
print $_ ." <- as.factor(" . $_ . "\n\t, levels = c(" ;
foreach (@levels){
print $_ . ",";
}
print ")\n\t, labels = c(";
foreach(@labels){
print $_ . ",";
}
print ")\n\t)\n";
}
И, наконец, вот пример вывода из сценария, как он в настоящее время работает:
gender <- as.factor(gender
, levels = c(1,2,1,2,3,)
, labels = c("M","F","biz","action","tiddlywinks",)
)
мне это нужно включать только уровни 1,2 и метки M и F.
Спасибо за помощь!
Ну, я думаю, это просто. Мне нужно потратить некоторое время, пытаясь переварить то, что вы там сделали, но я должен уметь это понять. Благодаря! – Chase
Можете ли вы объяснить второй оператор if в приведенном выше коде? Кажется, что «if (length $ current_label)» вернет true для каждой строки, нет? Это то, что вы намеревались? Является ли моя интерпретация следующей строки правильной: «if ($ line = ~/^ (\ d)» (. *) «$ /)« Говорит », если моя строка начинается с цифры, а затем хватайте все и все символы в пределах "" и помещать их в переменную $ 1? – Chase
@Chase, мне кажется, что вторая 'if' предназначена для пропуска« строк бессмыслицы »(предполагая, что они не начинаются с'/'). Это предотвращает регистрацию значений кода до тех пор, пока не найдет действительную метку (обратите внимание, что '$ current_label' инициализируется пустой строкой, длина которой не имеет длины). Лично я бы оставил' $ current_label' неинициализированным, а затем проверял для 'define $ current_label' вместо этого, но это тоже работает. – cjm