按R中的中值折叠重复的行

时间:2015-07-03 14:48:57

标签: r

我有一个有两列的日期框架。我想删除第一列中有重复条目的行。但是我想根据第二列的值选择一个特定的行。

具体而言 - 如果第1列中有2个重复条目,我希望第2列中的较低值删除该行

或者,如果第1列中有多于2个相同的条目,那么我希望保留第2行中具有中值的行。

因此对于数据框

a <- c(rep("A", 3), rep("B", 3), rep("C",1), rep("D",1), rep("D",1))
b <- c(1,2,3,4,5,6,4,7,6)
df <-data.frame(a,b)

会变成

a <- c(rep("A", 1), rep("B", 1), rep("C",1), rep("D",1))
b <- c(2,5,4,7)
df <-data.frame(a,b)

我尝试过函数unique()和duplicatelicated(),但似乎找不到符合这些条件的参数。任何帮助非常感谢。

2 个答案:

答案 0 :(得分:4)

你可以尝试

library(data.table)
setDT(df)[, list(b=if(.N==2) min(b) else median(b)) , by = a]
#   a b
#1: A 2
#2: B 5
#3: C 4
#4: D 6

aggregate

的类似选项
aggregate(b~a, df, FUN=function(x) if(length(x)==2) min(x) else median(x))
#  a b
#1 A 2
#2 B 5
#3 C 4
#4 D 6

或者

library(sqldf)
sqldf('select a, 
        case
          when count(b) is 2 then min(b)
          else median(b)
         end b 
       from df
       group by a')
 #  a b
 #1 A 2
 #2 B 5
 #3 C 4
 #4 D 6

根据显示的预期输出,最后一行是D 7,所以如果我们在组长度为2时选择第一个观察,

 setDT(df)[, list(b=if(.N==2) b[1L] else median(b)) , by = a]
 #   a b
 #1: A 2
 #2: B 5
 #3: C 4
 #4: D 7

或者

 aggregate(b~a, df, FUN=function(x) if(length(x)==2) x[1L] else median(x))
 #  a b
 #1 A 2
 #2 B 5
 #3 C 4
 #4 D 7

或者

 sqldf('select a,
           case 
             when count(b) is 2 and min(rowid) then b
             else median(b)
           end b
         from df
       group by a')
 #  a b
 #1 A 2
 #2 B 5
 #3 C 4
 #4 D 7
在我看到@ eipi10的帖子后,

编辑将第一次观察更改为min。没有正确读取OP的帖子,OP的预期输出与描述不符。

答案 1 :(得分:3)

使用dplyr

library(dplyr)

df %>% group_by(a) %>%
  summarise(b = ifelse(n() == 2, min(b), median(b)))

  a b
1 A 2
2 B 5
3 C 4
4 D 6

在你的问题中,你说你想要&#34;降低&#34;值,如果有两行,则给出D = 6,而不是D = 7。如果您的意思是数据框中出现的第一行,您可以这样做:

df %>% group_by(a) %>%
  summarise(b = ifelse(n() == 2, b[1], median(b)))
相关问题