Удаление записей на основе условий в SAS

Я совершенно новичок в SAS, и мне нужно выполнить простую задачу. скажем, у меня есть таблица вроде:

Мне нужно удалить все экземпляры sampCode, для которых хотя бы один SampCode отражает условие: 2*res > max. то есть удаление не только строки, но и всей группы sampCode на основе этого условия. Спасибо за помощь!

А что такое группа sampCode? Ваш sampCode имеет разное значение для каждой строки. Показать желаемый результат.

Negdo 16.12.2022 13:51

ты прав. Я заменил стол. Теперь для второй строки результат> 2*res > max, поэтому вывод не должен содержать ни одной записи 2014_AT14012534-001. надеюсь, теперь стало понятнее. Спасибо

efz 16.12.2022 14:37
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
67
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Попробуйте использовать двойной DoW Loop.
Предполагается, что ваш набор данных отсортирован по sampCode.

data want;
    _keep=1;
    
    do _n_=1 by 1 until (last.sampCode);
        set have;
        by sampCode;
        if 2*res>max then _keep=0;
    end;
    
    do _n_=1 by 1 until (last.sampCode);
        set have;
        by sampCode;
        if _keep=1 then output;
    end;
    
    drop _keep;
run;

В результате 2014_AT14012534-001 и 2014_AT14044069-001 удаляются.

       sampCode        res   max
 2014_AT14036758-001  0.01  0.066
 2014_AT14051994-001  0.01  0.021
 2014_BE2549-14-0021  0.01   0.33
 2014_BE2549-14-0023  0.01   0.06
 2014_BE3013-14-0118  0.01  0.044
 2014_BE3259-14-0019  0.01    0.1
 2014_BE3259-14-0101  0.01  0.037
 2014_BE3320-14-0200  0.01  0.038
 2014_BE3365-14-0005  0.01  0.021
 2014_BE4040-14-0548 0.005   0.11
 2014_BE4685-14-0018  0.01  0.054
 2014_BE4804-14-0057  0.01   0.18
 2014_BE4824-14-0007  0.01   0.03

Для подхода SQL попробуйте

proc sql;
    create table want as
    select sampCode, res, max 
    from (select sampCode, res, max, 
            max(case when 2*res>max then 1 else 0 end) as _max 
            from have 
            group by sampCode 
            having _max=0);
quit;

Если есть повторяющийся sampCode (например, 2014_AT14012534-001), у вас не будет всех наблюдений. Вам нужна двойная петля DoW.

Negdo 16.12.2022 15:27

Для данного его примера это не имеет значения, но в общем случае так и есть. Спасибо !

Kermit 16.12.2022 15:35

Первый индекс цикла _n_ будет вычислять размер группы в конце цикла. Второй цикл может быть простым _n_ = 1 to _n_; и не требует оператора BY внутри.

Richard 16.12.2022 16:53

Вы должны использовать двойной DOW, иначе вы получите только одно наблюдение на sampCode, даже в тех случаях, когда имеется множество наблюдений с одним и тем же sampCode.

  data have;
        informat sampCode $40.;
        input sampCode res max;
        datalines;
    2014_AT14012534-001 0.01 0.034
    2014_AT14012534-001 2 0.144
    2014_AT14012534-001 0.01 0.015
    2014_AT14012534-001 0.01 0.075
    2014_AT14012534-002 0.01 0.034
    2014_AT14012534-002 0.01 0.314
    2014_AT14012534-003 0.01 0.034
    2014_AT14012534-003 0.02 0.934
    2014_AT14012534-003 0.01 0.034
    2014_AT14012534-004 3 0.001
    run;



data want;
    keep=1;
    
    do until (last.sampCode);
        set have;
        by sampCode;
        if 2*res>max then keep=0;
    end;
    do until (last.sampCode);
        set have;
        by sampCode;
        if keep=1 then output;
    end;
    
    drop keep;
run;

Большое спасибо. Я попробую, но, поскольку в моих данных есть несколько строк 4M, подход do кажется слишком дорогим, хотя... Я думал, что это можно сделать с помощью некоторой процедуры sql

efz 16.12.2022 15:36

@efz Во многих случаях цикл DoW более эффективен, чем использование процедуры SQL. Я все равно отредактировал свой ответ с помощью SQL.

Kermit 16.12.2022 15:51

в следующий раз, если вы ищете ответ SQL, укажите это в вопросе и добавьте тег proc-sql

Kermit 16.12.2022 16:08

Чтобы проверить, истинно ли логическое выражение для ряда значений, просто используйте MAX(). SAS оценивает логические выражения как 1 (истина) или 0 (ложь). Таким образом, MAX() является истинным, если какое-либо значение истинно. В вашем случае вы хотите сохранить наблюдения, в которых условие никогда не выполняется, поэтому, когда MAX() является ложным.

PROC SQL с радостью объединит сводную статистику со всеми подробными наблюдениями.

select * 
  from have
  group by sampcode
  having not max(2*res > max)
;

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