【问题标题】:How to do row slice for defined groupings in a dataframe while excluding NAs?如何在排除 NA 的同时对数据框中定义的分组进行行切片?
【发布时间】:2017-10-16 08:03:50
【问题描述】:

我在 r 中有一个如下的数据框:

df<-data.frame(id=rep(1:3,each=2),date=rep(c(NA,"date1","date2"),each=2),value=rep(c(4.1,9.4,5.6,6),c(2,2,1,1)))
#   id  date value
# 1  1  <NA>   4.1
# 2  1  <NA>   4.1
# 3  2 date1   9.4
# 4  2 date1   9.4
# 5  3 date2   5.6
# 6  3 date2   6.0

我想从数据框中删除重复的行,这样如果有超过 1 行具有相同的 id、相同的日期和相同的值,那么我将只取第一行并删除其他行。

我的第一反应是:

library(dplyr)
df %>% group_by(id,date,value) %>% slice(1)

但是,我想要的是

#   id  date value
# 1  1  <NA>   4.1
# 2  1  <NA>   4.1
# 3  2 date1   9.4
# 4  3 date2   5.6
# 5  3 date2   6.0

对于“日期”为空的行,忽略 slice(1)

我该怎么做?

【问题讨论】:

    标签: r dplyr slice


    【解决方案1】:

    我们可以使用filter

    library(dplyr)
    df %>% 
        filter(is.na(date)|!duplicated(cbind(id, date, value)))
    #   id  date value
    #1  1  <NA>   4.1
    #2  1  <NA>   4.1
    #3  2 date1   9.4
    #4  3 date2   5.6
    #5  3 date2   6.0
    

    slice

    df %>%
        group_by(id,date,value) %>%
         slice(unique(c(1, which(is.na(date)))))
    # A tibble: 5 x 3
    # Groups: id, date, value [4]
    #     id   date value
    #  <int> <fctr> <dbl>
    #1     1     NA   4.1
    #2     1     NA   4.1
    #3     2  date1   9.4
    #4     3  date2   5.6
    #5     3  date2   6.0
    

    使用base R,我们可以更紧凑地做到这一点

    df[!duplicated(df) |is.na(df$date),]
    #  id  date value
    #1  1  <NA>   4.1
    #2  1  <NA>   4.1
    #3  2 date1   9.4
    #5  3 date2   5.6
    #6  3 date2   6.0
    

    【讨论】:

    • 对于base R 示例,我尝试将duplicated 中的参数从df 替换为cbind(id, date, value),但它不起作用。这是为什么呢?
    • @HNSKD 如果id, date 对象不是单独创建的,它就不起作用,因为它在'df'的环境中。您可能需要cbind(d$id, d$date, ...df[!duplicated(with(df, cbind(id, date, value))) |is.na(df$date),]
    猜你喜欢
    • 2019-01-12
    • 2020-12-26
    • 2017-08-13
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 2010-11-23
    • 1970-01-01
    相关资源
    最近更新 更多