Я пытаюсь удалить слова из поля в SAS, используя таблицу слов.
Мне удалось изолировать каждое слово с помощью некоторого кода, который я нашел в Интернете, но я не могу удалить слово из поля.
Например, если поле:
«Лисица перепрыгнула через луну»
если в списке слов есть слово "прыгнул", то результат должен выглядеть так:
«Лисица над луной»
Вот таблица стоп-слов для удаления:
PROC SQL;
CREATE TABLE BOW.QUERY_FOR_STOPWORDS AS
SELECT t1.StopWords
FROM BOW.STOPWORDS t1;
QUIT;
Вот таблица с полем, которое нужно удалить:
PROC SQL;
CREATE TABLE WORK.QUERY_FOR_ANNU_COMMENTS AS
SELECT t1.Comment
FROM BOW.ANNU_COMMENTS t1;
QUIT;
Основная идея replace()
:
SELECT REPLACE(t1.Comment, 'jumped', '')
FROM BOW.ANNU_COMMENTS t1;
Однако у вас проблемы с пробелами. Если это проблема и вам нужны полные слова, это может сработать:
SELECT TRIM(BOTH ' ' FROM REPLACE(' ' || t1.Comment || ' ', ' jumped ', ''))
FROM BOW.ANNU_COMMENTS t1;
Мне нужно использовать все слова в таблице SELECT t1.StopWords FROM BOW.STOPWORDS, а не только слова "прыгнул"
В зависимости от того, сколько слов у вас есть другие решения.
data _NULL_;
set STOPWORDS end=e;
if _N_=1 then call execute('data result;set ANNU_COMMENTS;newComment=Comment;');
call execute('if _N_=1 then __'||put(_N_,z30.)||'+prxparse("s/'||trimn(StopWords)||'//");');
call execute('call prxchange(__'||put(_N_,z30.)||',-1,newComment);');
if e then call execute('drop __:;run;');
run;
Это займет стоп-слова и сгенерирует шаг данных из него, чем комментарии процесса этого шага данных.
Обновлено: Чтобы удалить только слова по границе слова, вы должны использовать \b в регулярном выражении.
data _NULL_;
set STOPWORDS end=e;
if _N_=1 then call execute('data result;set ANNU_COMMENTS;newComment=Comment;');
call execute('if _N_=1 then __'||put(_N_,z30.)||'+prxparse("s/\b'||trimn(StopWords)||'\b//");');
call execute('call prxchange(__'||put(_N_,z30.)||',-1,newComment);');
if e then call execute('drop __:;run;');
run;
Привет Ли, Как я могу заставить это создать новое поле без каких-либо стоп-слов и поместить его рядом с полем комментария как «новый комментарий»
Сначала просто скопируйте новую переменную, а затем измените ее. Я отредактировал код, чтобы отразить это.
Я получаю следующую ошибку: 582 + если _N_=1 then __00000000000000000000000000000291+prxparse("s/HERSE"//");" __ 388 76 ОШИБКА 388-185: Ожидается арифметический оператор. ОШИБКА 76-322: Синтаксическая ошибка, инструкция будет проигнорирована.
ПРИМЕЧАНИЕ. Система SAS прекратила обработку этого шага из-за ошибок. ВНИМАНИЕ! Набор данных WORK.RESULT может быть неполным. Когда этот шаг был остановлен, было 0 наблюдений и 25 переменных. ВНИМАНИЕ! Набор данных WORK.RESULT не был заменен, так как этот шаг был остановлен.
Это потому, что ваше слово имеет "внутри
Это работало, но, может быть, слишком хорошо. У меня есть отдельные буквы в списке слов. Теперь все буквы удалены. остались только цифры. Есть ли способ, чтобы для каждого слова работали только точные совпадения, а не буквы?
@cartoom02 cartoom02 я добавил измененный вариант
Большое спасибо, это сработало отлично, теперь нужно только очистить лишние пробелы, для которых у меня есть код.
Вы можете попробовать использовать хеш-итератор, например:
data want;
if 0 then set STOPWORDS;
if _n_=1 then do;
declare hash h(dataset:'STOPWORDS');
declare hiter iter('h');
h.definekey('StopWords');
h.definedata('StopWords');
h.definedone();
end;
set ANNU_COMMENTS;
rc=iter.first();
do while(rc=0);
newComment=ifc(findw(newComment,strip(StopWords))>0,tranwrd(newComment,strip(StopWords),''),newComment);
rc=iter.next();
end;
drop StopWords rc;
run;
Можно написать макрос, который генерирует шаг очистки данных.
В этом примере смешивается использование Шэнлином tranwrd с codegen Ли.
%macro flense (
data=Commments,
var=Comment,
newvar=CommentFlensed,
censor=BOW.StopWordsList,
term=StopWords
);
proc sql noprint;
select quote(trim(&term),"'") into :sq_word1-; * single quote the words to prevent possible macro evaluation later;
from &censorData;
data &out;
set &data;
&newvar = &var;
%* for each censored word, generate an if statement
* that checks if the word (or term) is present, and if so
* removes the word from the new variable;
%local i quoted_word;
%do i = 1 %to &SQLOBS;
%let quoted_word = &&&sq_word&i;
if (indexw(&newvar.,"ed_word)) then
&newvar = tranwrd(&newvar,"ed_word,'');
%end;
run;
%mend;
%flense();
на всякий случай, если вы ищете динамическую замену. sqlservercentral.com/forums/topic/…