【问题标题】:How do I only keep observations based on the max values after their decimal point?如何仅根据小数点后的最大值保留观察结果?
【发布时间】:2018-12-31 08:34:53
【问题描述】:

我想做这个数据框:

(已编辑以显示它是一个多于 1 列的实际数据框)

ID = c(100.00, 100.12, 100.36, 101.00, 102.00, 102.24, 103.00, 103.36, 103.90)
blood = c(55, 54, 74, 42, 54, 45, 65, 34, 44)
df = data.frame(ID, blood)

  ID       blood
1 100.00    55
2 100.12    54
3 100.36    74
4 101.00    42
5 102.00    54
6 102.24    45
7 103.00    65
8 103.36    34
9 103.90    44

成为这个:

ID = c(100.36, 101.00, 102.24, 103.36)
df2 = data.frame(ID)

  ID2        blood2
1 100.36     74
2 101.00     42
3 102.24     45
4 103.90     44

换句话说,对于任何给定的整数(如 102),我只想保留它的最高十进制版本。所以基本上我需要告诉 R 只保留每个整数的最高“版本”。有什么想法吗?

【问题讨论】:

    标签: r data-cleaning


    【解决方案1】:
    > ID = c(100.00, 100.12, 100.36, 101.00, 102.00, 102.24, 103.00, 103.36)
    > ID2 <- tapply( ID, floor(ID), FUN=max)
    > ID2
       100    101    102    103 
    100.36 101.00 102.24 103.36 
    > (df2 <- data.frame(ID2))
           ID2
    100 100.36
    101 101.00
    102 102.24
    103 103.36
    > (df2 <- data.frame(ID=as.vector(ID2)))
          ID
    1 100.36
    2 101.00
    3 102.24
    4 103.36
    

    扩展

    > ID = c(100.00, 100.12, 100.36, 101.00, 102.00, 102.24, 103.00, 103.36, 103.9)
    > blood = c(55, 54, 74, 42, 54, 45, 65, 34, 44)
    > df = data.frame(ID, blood)
    > 
    > tmp <- tapply( df$ID, floor(df$ID), FUN=function(x) x==max(x))
    > 
    > (df2 <- df[unlist(tmp),])
          ID blood
    3 100.36    74
    4 101.00    42
    6 102.24    45
    9 103.90    44
    

    【讨论】:

    • 这可能是最有效的答案,只是想知道如果我有与列关联的其他数据,我该如何修改它? (我编辑了原始问题以显示这一点)
    【解决方案2】:

    这是一个使用base R的选项

    df[with(df, ave(ID, floor(ID), FUN = max) == ID),, drop = FALSE]
    

    【讨论】:

      【解决方案3】:
      > df$X<- gsub("\\.\\d*", "", as.character(df$ID))
      > df <- aggregate(ID~X, df, max)
      > df$X <- NULL
      > df
            ID
      1 100.36
      2 101.00
      3 102.24
      4 103.36
      

      【讨论】:

        【解决方案4】:

        这是使用dplyr 包的可能解决方案。

        library(dplyr)
        df2 <- df %>%
          mutate(pre = floor(ID), post = ID - floor(ID)) %>%
          arrange(pre, desc(post)) %>%
          group_by(pre) %>%
          filter(row_number() == 1) %>%
          ungroup() %>%
          select(ID)
        

        【讨论】:

        • 要了解其工作原理,请运行到链中的任何步骤并查看df2
        • 可爱,看起来我只是使用 select(ID, x, y, z) 来保留与我想要保留的行关联的其余列。谢谢
        • @StatsNTats 请选择此答案或任何其他已接受的答案,以最适合您的为准。
        【解决方案5】:

        使用dplyr 的选项可以是:

        library(dplyr)
        
        df %>% group_by(IntPart = floor(ID)) %>%
          filter(ID == max(ID)) %>% 
          ungroup() %>%
          select(-IntPart) %>%
          as.data.frame() 
        
        #       ID blood
        # 1 100.36    74
        # 2 101.00    42
        # 3 102.24    45
        # 4 103.90    44
        

        【讨论】:

          【解决方案6】:

          你可以使用aggregate:

          subset(df, ID %in% aggregate(ID ~ floor(df$ID), df, max)$ID)
          #       ID blood
          # 3 100.36    74
          # 4 101.00    42
          # 6 102.24    45
          # 9 103.90    44
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-22
            • 1970-01-01
            • 2021-06-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多