从这样的 Dataframe
test <- data.frame('id'= rep(1:5,2), 'string'= LETTERS[1:10])
test <- test[order(test$id), ]
rownames(test) <- 1:10
> test
id string
1 1 A
2 1 F
3 2 B
4 2 G
5 3 C
6 3 H
7 4 D
8 4 I
9 5 E
10 5 J
我想用每个id / string对的第一行创建一个新的查询,如果sqldf在其中接受R代码,查询可能如下所示:
res <- sqldf("select id, min(rownames(test)), string
from test
group by id, string")
> res
id string
1 1 A
3 2 B
5 3 C
7 4 D
9 5 E
除了创建一个新列(如
test$row <- rownames(test)
并运行带有min(row)的相同sqldf查询?
8条答案
按热度按时间jaxagkaj1#
您可以使用
duplicated
非常快速地完成此操作。速度狂人的基准:
让我们再试一次,但只有来自第一轮的竞争者,并有更多的数据和更多的复制。
6pp0gazn2#
我喜欢dplyr的方法。
group_by(id)
,后跟filter(row_number()==1)
或slice(1)
或slice_head(1)
#(厚度=〉1.0)top_n(n = -1)
top_n()
内部使用秩函数。负从秩的底部选择。在某些情况下,可能需要将id安排在group_by之后。
所有三个方法都返回相同的结果
fd3cxomn3#
怎么样
编辑
data.tables
还有一个独特的方法,它将按键返回第一行我认为,如果您在基准测试之外订购
test
,那么您也可以从基准测试中删除setkey
和data.table
转换(因为setkey基本上按id排序,与order
相同)。有了更多的数据
使用唯一方法编辑
独特的方法在这里是最快的。
yqkkidmi4#
一个简单的
ddply
选项:如果速度是个问题,可以对
data.table
采取类似的方法:或者这可能会快很多
svdrlsy45#
现在,对于
dplyr
,添加不同的计数器。你创建组,他们在组内总结。
如果数据是数值,则可以用途:
first(value)
[还有last(value)
]代替了head(value, 1)
参见:http://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html
完整:
rggaifut6#
(1)SQLite有一个内置的
rowid
伪列,因此可以这样工作:给出:
(2)
sqldf
本身也有一个row.names=
参数:给出:
(3)将上述两种要素混合在一起的第三种备选办法可能更好:
给出:
请注意,所有这三个都依赖于SQLite对SQL的扩展,其中使用
min
或max
保证会导致从同一行中选择其他列(在其他基于SQL的数据库中,这可能无法保证)。ffscu2ro7#
基本R选项是
split()
-lapply()
-do.call()
习惯用法:更直接的选择是
lapply()
[
函数:lapply()
调用末尾的逗号空格1, )
是必不可少的,因为这相当于调用[1, ]
来选择第一行和所有列。xqk2d5yq8#
在
dplyr 1.1.0
中,您可以对slice
使用内联分组: