Удалить слова из поля, используя слова из таблицы в SAS

Я пытаюсь удалить слова из поля в 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;

на всякий случай, если вы ищете динамическую замену. sqlservercentral.com/forums/topic/…

Mani Deep 08.04.2019 13:41
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
1
336
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Основная идея 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, а не только слова "прыгнул"

cartoom02 08.04.2019 13:43
Ответ принят как подходящий

В зависимости от того, сколько слов у вас есть другие решения.

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;

Привет Ли, Как я могу заставить это создать новое поле без каких-либо стоп-слов и поместить его рядом с полем комментария как «новый комментарий»

cartoom02 08.04.2019 15:17

Сначала просто скопируйте новую переменную, а затем измените ее. Я отредактировал код, чтобы отразить это.

Lee 08.04.2019 15:19

Я получаю следующую ошибку: 582 + если _N_=1 then __00000000000000000000000000000291+prxparse("s/HERSE"//");" __ 388 76 ОШИБКА 388-185: Ожидается арифметический оператор. ОШИБКА 76-322: Синтаксическая ошибка, инструкция будет проигнорирована.

cartoom02 08.04.2019 16:20

ПРИМЕЧАНИЕ. Система SAS прекратила обработку этого шага из-за ошибок. ВНИМАНИЕ! Набор данных WORK.RESULT может быть неполным. Когда этот шаг был остановлен, было 0 наблюдений и 25 переменных. ВНИМАНИЕ! Набор данных WORK.RESULT не был заменен, так как этот шаг был остановлен.

cartoom02 08.04.2019 16:20

Это потому, что ваше слово имеет "внутри

Lee 08.04.2019 20:14

Это работало, но, может быть, слишком хорошо. У меня есть отдельные буквы в списке слов. Теперь все буквы удалены. остались только цифры. Есть ли способ, чтобы для каждого слова работали только точные совпадения, а не буквы?

cartoom02 13.05.2019 19:38

@cartoom02 cartoom02 я добавил измененный вариант

Lee 14.05.2019 08:39

Большое спасибо, это сработало отлично, теперь нужно только очистить лишние пробелы, для которых у меня есть код.

cartoom02 14.05.2019 12:48

Вы можете попробовать использовать хеш-итератор, например:

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.,&quoted_word)) then 
        &newvar = tranwrd(&newvar,&quoted_word,'');

    %end;
  run;

%mend;

%flense();

Другие вопросы по теме

Похожие вопросы