小技巧-只删除某一列中含NA的行(R)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小技巧-只删除某一列中含NA的行(R)相关的知识,希望对你有一定的参考价值。

参考技术A

目的 :只删除数据框“human_f_score”中“σf”这一列里所有含NA的行

方法:使用tidyr包里的drop_na()

仅返回一列中的日期与另一列中的日期最接近的行?

【中文标题】仅返回一列中的日期与另一列中的日期最接近的行?【英文标题】:Return only the row where the date in one column is closest to the date in another column? 【发布时间】:2021-06-04 19:54:29 【问题描述】:

我正在处理一个查询,但它返回了一些重复的值,我只需要返回一列中的日期与另一列中的日期最接近的行。

我的查询如下所示:

SELECT p.Id, r.ReferralDate, s.SupervisionDate
FROM person p
INNER JOIN referral r on r.PersonId = p.Id 
INNER JOIN supervision s on s.PersonId = p.Id

返回如下内容:

Id Supervision Date Referral Date
123 2015-09-30 2015-08-30
123 2020-02-30 2015-08-30
123 2020-06-30 2015-08-30
456 2010-06-30 2010-07-30
456 2005-06-30 2010-07-30

如何编写一个查询来返回最接近推荐日期的监督日期?这样最终的输出看起来像这样:

Id Supervision Date Referral Date
123 2015-09-30 2015-08-30
456 2010-06-30 2010-07-30

【问题讨论】:

【参考方案1】:

在这种情况下,您可以使用两种方式来选择您需要的记录。

    我更喜欢这种方式,因为它是非常有效的解决方案。我们按日期差异获取行顺序并选择最小日期差异。第一种方式,您可以选择要显示的列。这也是更通用的解决方案。

    SELECT  A.Id
     , A.ReferalDate
     , A.Supervision 
    
    FROM 
    (
    
     SELECT 
       p.Id
       , r.ReferalDate
       , s.Supervision   
       ,ROW_NUMBER() OVER (PARTITION BY p.Id ORDER BY  DATEDIFF(DD,r.ReferalDate,s.Supervision) ASC) as [row_num]
      FROM person p
         INNER JOIN referral r 
            on r.pid = p.Id 
         INNER JOIN supervision s 
           on s.pid = p.Id
     ) AS A 
    WHERE A.row_num = 1
    

    这样我们按日期差异排序并获得前 1 条记录。如果将此添加到 CTE 或派生表中,您仍然可以只返回您需要的列。此查询是特定于场景的,因为我们不考虑分区。

    SELECT top 1
        p.Id
       , r.ReferalDate
       , s.Supervision   
       ,DATEDIFF(DD,r.ReferalDate,s.Supervision) as [date dif]
    FROM person p
    INNER JOIN referral r 
        on r.pid = p.Id 
    INNER JOIN supervision s 
        on s.pid = p.Id
    ORDER BY [date dif] ASC
    

两种方式都返回相同的结果,因为我们的订单是在日期差异上下达的。

【讨论】:

【参考方案2】:

这是一种方法:

select p.Id, r.ReferralDate, s.SupervisionDate from (
 select p.Id, r.ReferralDate, s.SupervisionDate , row_number() over (partition by id order by abs(datediff(day , ReferralDate,SupervisionDate))) rn
 from person p
 join referral r on r.PersonId = p.Id 
 join supervision s on s.PersonId = p.Id
) t
where rn = 1

【讨论】:

【参考方案3】:

另一种方式:

select ID, SUP from 
( SELECT 
   p.Id 'ID', 
   r.ReferralDate 'REF', 
   s.SupervisionDate 'SUP',
   min(julianday(s.SupervisionDate) - julianday(r.ReferralDate) ) 'diff'

FROM person p
INNER JOIN referral r on r.PersonId = p.Id 
INNER JOIN supervision s on s.PersonId = p.Id

GROUP BY p.ID
)

这将根据要求返回 ID 和 SupervisionDate。

【讨论】:

除非我很困惑,否则这将总共返回 1 行,而不是每个 id 1 行。 @Andrew 你是绝对正确的,发帖人的例子只使用了 ID 123,所以我没有考虑到会有其他 ID。帖子会更新的,我的错。显示良好的采样日期有多重要。 有没有 julianday() 的替代方法?它在 SQL Server 中不起作用。 @JLo,抱歉,将您的问题读为 SQLite。对于 MSSQL,我相信您可以使用 DATEDIFF(day, firstdate, seconddate) 而不是朱利安日期之间的差异。然后只需选择其中的最小值。 这个答案使用的是 SQLLIte 中的一些函数 julianday()。

以上是关于小技巧-只删除某一列中含NA的行(R)的主要内容,如果未能解决你的问题,请参考以下文章

Excel技巧:判断某一列中的数据是不是在另一列中

R - 检查 r 数据框行的任何列中是不是存在 NA,如果存在,则删除该行 [重复]

R 小知识积累

EXCEL函数 如何删除某一列中不含某一元素的行

R:一次根据一列中的条件将整行推送到NA

小技巧