這有什麼錯用proc sort
和nodup
選項?
proc sort data=emp nodup;
by empid;
run;
第二個答案:
如果無法創建一個表,無論是直接或使用proc sort
例如,那麼我相信你唯一的選擇是使用與modify
語句數據的步驟。這會更新現有的數據集,而不是創建新的數據集,並在代碼成功運行時替換現有的數據集。
由於您的數據似乎未排序,因此需要更具創造性的方法,而不是使用排序數據完成的簡單first.empid
。我所做的是在讀取數據集時建立唯一值列表,然後查找該列表中的當前值。如果存在,則該行被刪除。沒有必要刪除我創建的臨時字段(_list
),因爲modify
不允許添加新字段,它僅在幕後使用。
請注意,以這種方式刪除記錄(並使用proc sql
中的delete from
語法)不會實際刪除記錄,只會將它們標記爲已刪除,因此在查看或查詢時不會顯示記錄。如果您在運行代碼後打開Emp數據集,則會看到缺少行號。
data emp;
modify emp;
length _list $200; /* set length of temporary field */
retain _list; /* retain existing values */
if findw(_list,strip(empid))>0 then remove; /* delete observation if empid already exists */
else call catx(',',_list,empid); /* add current empid to list if it doesn't already exist */
run;
我應該補充說這個答案不是很有伸縮性,如果你有一個包含許多唯一值的大數據集,那麼_list變量將需要很長的長度來適應它們。如果Emp數據集按EmpId排序或至少編制索引,則更好的選擇是。這樣,你可以做以下(EMP在set
語句包含兩次爲by
說法是,只有當有2個數據集在set
聲明有效。這是一招讓first.
處理。)
data emp;
modify emp (obs=0) emp;
by empid;
if not first.empid then remove;
run;
@ Gordon-Linoff我的同事問我這個問題。有許多解決方案,如proc sort,data first first。最後一個,不同的sql。但是這也可以使用刪除查詢。他已經提到它具有開箱即用的答案,所以挖掘更多。如果你沒有權限創建表格會怎麼樣。那麼proc排序將不起作用。他補充說,它有點複雜。不知道如何實現這一點 –