Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
dplyr筛选器:获取具有最小变量的行,但如果有多个最小值,则仅获取第一行_R_Dplyr - Fatal编程技术网

dplyr筛选器:获取具有最小变量的行,但如果有多个最小值,则仅获取第一行

dplyr筛选器:获取具有最小变量的行,但如果有多个最小值,则仅获取第一行,r,dplyr,R,Dplyr,我想使用dplyr创建一个分组过滤器,在每个组中只返回最小值为变量x的行 我的问题是:正如预期的那样,在多个最小值的情况下,返回具有最小值的所有行。但是在我的例子中,如果存在多个极小值,我只想要第一行 下面是一个例子: df <- data.frame( A=c("A", "A", "A", "B", "B", "B", "C", "C", "C"), x=c(1, 1, 2, 2, 3, 4, 5, 5, 5), y=rnorm(9) ) library(dplyr) df.g <

我想使用
dplyr
创建一个分组过滤器,在每个组中只返回最小值为变量
x
的行

我的问题是:正如预期的那样,在多个最小值的情况下,返回具有最小值的所有行。但是在我的例子中,如果存在多个极小值,我只想要第一行

下面是一个例子:

df <- data.frame(
A=c("A", "A", "A", "B", "B", "B", "C", "C", "C"),
x=c(1, 1, 2, 2, 3, 4, 5, 5, 5),
y=rnorm(9)
)

library(dplyr)
df.g <- group_by(df, A)
filter(df.g, x == min(x))
有了ddply,我将以这种方式完成任务:

library(plyr)
ddply(df, .(A), function(z) {
    z[z$x == min(z$x), ][1, ]
})
。。。有效的方法是:

  A x           y
1 A 1 -1.04584335
2 B 2  0.79600971
3 C 5 -0.08655151

Q:在dplyr中是否有一种方法可以实现这一点?(出于速度原因)

对于它的价值,这里有一个
数据表
解决方案,供可能感兴趣的人使用:

# approach with setting keys
dt <- as.data.table(df)
setkey(dt, A,x)
dt[J(unique(A)), mult="first"]

# without using keys
dt <- as.data.table(df)
dt[dt[, .I[which.min(x)], by=A]$V1]
#使用设置键接近

dt只是为了完整性:这里是最终的
dplyr
解决方案,来自@hadley和@Arun的评论:

library(dplyr)
df.g <- group_by(df, A)
filter(df.g, rank(x, ties.method="first")==1)
库(dplyr)
df.g更新
当dplyr>=0.3时,您可以将
slice
功能与
which.min
结合使用,这将是我最喜欢的执行此任务的方法:

df %>% group_by(A) %>% slice(which.min(x))
#Source: local data frame [3 x 3]
#Groups: A
#
#  A x          y
#1 A 1  0.2979772
#2 B 2 -1.1265265
#3 C 5 -1.1952004

原始答案 对于样本数据,也可以在每个样本数据之后使用两个
过滤器

group_by(df, A) %>% 
  filter(x == min(x)) %>% 
  filter(1:n() == 1)

这可以通过使用
行编号
分组依据
组合来实现<代码>行编号
通过不仅根据值,而且根据向量内的相对顺序分配秩来处理关系。要获取最小值为
x
的每组第一行:

df.g <- group_by(df, A)
filter(df.g, row_number(x) == 1)

df.g我喜欢sqldf,因为它简单

sqldf("select A,min(X),y from 'df.g' group by A")
输出:

A min(X)          y

1 A      1 -1.4836989

2 B      2  0.3755771

3 C      5  0.9284441
另一种方法是:

set.seed(1)
x <- data.frame(a = rep(1:2, each = 10), b = rnorm(20))
x <- dplyr::arrange(x, a, b)
dplyr::filter(x, !duplicated(a))

也可以很容易地调整以获得每组中具有最大值的行

来这里是想找到一种方法,用一个以上的。我相信,这会让排名倒数第十的球队最终打破平局

df.g %>%
top_n(-10,row_number(x))

dplyr
提供了
slice\u min
函数,该函数使用参数
执行任务,参数=FALSE

library(dplyr)

df %>% 
  group_by(A) %>% 
  slice_min(x, with_ties = FALSE)
输出:

# A tibble: 3 x 3
# Groups:   A [3]
A         x      y
<fct> <dbl>  <dbl>
1 A         1  0.273
2 B         2 -0.462
3 C         5  1.08 
#一个tible:3 x 3
#分组:A[3]
A x y
1A 10.273
2b2-0.462
3 C 5 1.08

过滤器(df.g,秩(x)=1)
?@FelixS,
秩(x)=1
是否给出了所需的结果?@hadley,1)我认为
最小秩
在这里没有帮助。他需要第一个最小值(查看
plyr
solution)。2) 在您编写的任何编程语言中,
rank
(ties=min,max,first等)的算法复杂度将比只计算
min
@Arun:True,只有
rank(x,ties.method=“first”)==1
起作用,因为min和min\u-rank不区分多个极小值。@hadley,我仍然不明白这是怎么让你考虑<代码>的。MIN <代码>是早熟的优化。好吧,这是一个自然的选择,读起来很好,很容易理解,速度也很快。我发现
do(head)
更容易阅读,
df%%>%group\u by(a)%%>%filter(x==min(x))%%>%do(head(,1))
@baptiste看起来确实不错(但是,当我运行它时,我收到一条错误消息
error:需要一个值
)-你知道为什么吗?不确定,也许我们使用的是不同的版本;我有
dplyr_0.2,magrittr_1.0.0
Ok,所以问题是我仍然在运行dplyr 0.1.3。我更愿意在这里使用
top\n
,但由于关系密切,这种方法可能是明显的赢家-在性能方面(与
arrange%>%slice
相比)肯定是如此。这是我最喜欢的答案!
library(dplyr)

df %>% 
  group_by(A) %>% 
  slice_min(x, with_ties = FALSE)
# A tibble: 3 x 3
# Groups:   A [3]
A         x      y
<fct> <dbl>  <dbl>
1 A         1  0.273
2 B         2 -0.462
3 C         5  1.08