假设我有一个R数据框,包含3列 A , B 和 C ,其中 A 价值观并非完全不同。
如何获取A的所有值,B的值最小为C(对于A的值)?
类似于伪SQL代码:SELECT C WHERE B = MIN(B) GROUPBY A
?
我查看了aggregate()
函数,但我不确定它是否可以完成。
aggregate(B ~ A, data = mydataframe, min)
只给出了每个A的B的最小值,但后来我不知道如何得到相应的C值。
是否有办法使用此聚合的结果对数据框进行子集以获取C值,和/或是否可以仅在aggregate()
的一次调用中完成?
由于
我想得到的一个例子:
输入:
A B C
1 0 1
1 2 2
1 1 3
1 1 4
2 1 1
2 2 2
2 0 3
2 3 4
输出:
1
3
1是对应于A = 1
的B(0)的最小值的C的值3是对应于A = 2
的B(0)的最小值的C的值答案 0 :(得分:4)
您可以使用data.table
包:
library(data.table)
DT <- as.data.table(mydataframe)
DT[ , C[which.min(B)], by = "A"]
# A V1
# 1: 1 1
# 2: 2 3
或dplyr
:
library(dplyr)
mydataframe %.%
group_by(A) %.%
summarise(res = C[which.min(B)])
# A res
# 1 2 3
# 2 1 1
或基本功能by
:
by(mydataframe, mydataframe$A, function(x) x$C[which.min(x$B)])
# mydataframe$A: 1
# [1] 1
# -------------------------------------------------------------------------------
# mydataframe$A: 2
# [1] 3
答案 1 :(得分:4)
1) SQLite保证当您使用min
或max
时,其他列变量将来自同一行,因此我们得到一个特别简单的解决方案:
library(sqldf)
# one minimum per group
sqldf("select A, min(B) B, C from DF group by A")
如果可能存在重复的最小值并且我们想要所有这些,那么使用correlated subquery进行选择就可以了:
# all minima per group
sqldf("select * from DF x
where x.b = (select min(y.b) from DF y where y.a = x.a)")
2)在R的基础上使用ave
我们可以这样做:
# one minimum per group
subset(DF, !! ave(B, A, FUN = function(x) seq_along(x) == which.min(x)))
# all minima per group
subset(DF, !! ave(B, A, FUN = function(x) x == min(x)))
3)如果您确实想使用aggregate
,请执行以下操作:
# one minimum per group
sq <- 1:nrow(DF)
DF[aggregate(sq ~ A, DF, function(ix) ix[which.min(DF$B[ix])])$sq, ]
答案 2 :(得分:3)
您可以对A和B列上的表进行排序:
d<-structure(list(A = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), B = c(0L,
2L, 1L, 1L, 1L, 2L, 0L, 3L), C = c(1L, 2L, 3L, 4L, 1L, 2L, 3L,
4L)), .Names = c("A", "B", "C"), class = "data.frame", row.names = c(NA,
-8L))
d2<-d[order(d$A, d$B),]
数据框d2应如下所示:
A B C
1 1 0 1
3 1 1 3
4 1 1 4
2 1 2 2
7 2 0 3
5 2 1 1
6 2 2 2
8 2 3 4
由于在排序数据帧中,B的值在A的每个值内都按升序排列,因此每个不同A值的第一行是对应于B的最小值的那一行。
然后,使用函数duplicated()
和通常的下标,删除A中没有重复的所有行,并仅返回C中的值(第三列):
d2[!duplicated(d2$A),3]
[1] 1 3