我有一个有两列的日期框架。我想删除第一列中有重复条目的行。但是我想根据第二列的值选择一个特定的行。
具体而言 - 如果第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(),但似乎找不到符合这些条件的参数。任何帮助非常感谢。
答案 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)))