我如何只保留基于小数点后最大值的观察值?

How do I only keep observations based on the max values after their decimal point?

我想制作这个数据框:

(经过编辑以显示它是一个多于 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 只保留每个整数中最高的 "version"。有什么想法吗?

这是使用 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)

这是一个使用base R

的选项
df[with(df, ave(ID, floor(ID), FUN = max) == ID),, drop = FALSE]
> 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
> 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

使用 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

你可以使用 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