我有一个数据框,比如说
df <- data.frame(x = c(1,2,5,6,3,3,3,6,8,8,8,8),
y = c(1,1,1,1,1,2,3,1,1,2,3,4),
z = c("a","b","c","d","e","f","g","h","i","j","k","l"))
看起来像这样
x y z
1 1 1 a
2 2 1 b
3 5 1 c
4 6 1 d
5 3 1 e
6 3 2 f
7 3 3 g
8 6 1 h
9 8 1 i
10 8 2 j
11 8 3 k
12 8 4 l
我想从列x中选择唯一的元素,基于列y使得y应该是最大的(在这种情况下,对于行号5到7是3'3,我想选择x = 3对应于y = 3(最大值),类似于x = 8,我想选择y = 4行)
输出应该如下所示
x y z
1 1 1 a
2 2 1 b
3 5 1 c
4 6 1 d
5 3 3 g
6 6 1 h
7 8 4 l
我有一个解决方案,我在解决方案中发布,但如果有更好的方法来实现这一点,我的解决方案只适用于这种特定情况(选择最大的)什么是一般案例解决方案此?
答案 0 :(得分:2)
使用dplyr
library(dplyr)
df %>%
group_by(x) %>%
slice(max(y))
# x y z
# (dbl) (dbl) (chr)
#1 1 1 a
#2 2 1 b
#3 3 3 g
#4 5 1 c
#5 6 1 d
#6 8 4 l
base R
替代方案正在使用aggregate
aggregate(y~x, df, max)
答案 1 :(得分:2)
您可以使用dplyr
链和dplyr
的{{1}}函数获得相同的结果。使用group_by
函数后,链中的其余函数将应用于组中,而不是整个data.frame。所以,group_by
每个filter
的分组值max(y)
只留下x
。这可以扩展为用于min
y
或特定值。
我认为使用ungroup
来group_by
链末尾的数据通常是一种很好的做法,以避免任何意外行为。
library(dplyr)
df <- data.frame(x = c(1,2,5,6,3,3,3,6,8,8,8,8),
y = c(1,1,1,1,1,2,3,1,1,2,3,4),
z = c("a","b","c","d","e","f","g","h","i","j","k","l"))
df %>%
group_by(x) %>%
filter(y==max(y)) %>%
ungroup()
为了使其更通用...而是说您希望mean
y
代表x
而不是max
。然后,您可以使用summarise
函数代替filter
,如下所示。
df %>%
group_by(x) %>%
summarise(y=mean(y)) %>%
ungroup()
答案 2 :(得分:1)
使用data.table
我们可以使用df[order(z), .I[which.max(y)], by = x]
来获取感兴趣的rownumbers,例如:
library(data.table)
setDT(df)
df[df[order(z), .I[which.max(y)], by = x][, V1]]
x y z
1: 1 1 a
2: 2 1 b
3: 5 1 c
4: 6 1 d
5: 3 3 g
6: 8 4 l
答案 3 :(得分:0)
这是我使用dplyr软件包的解决方案
library(dplyr)
df <- data.frame(x = c(1,2,5,6,3,3,3,6,8,8,8,8),
y = c(1,1,1,1,1,2,3,1,1,2,3,4),
z = c("a","b","c","d","e","f","g","h","i","j","k","l"))
df <- arrange(df,desc(y))
df_out <- df[!duplicated(df$x),]
df_out
打印df_out
x y z
1 8 4 l
2 3 3 g
6 1 1 a
7 2 1 b
8 5 1 c
9 6 1 d
答案 4 :(得分:0)
假设数据框按照示例中的df[order(df$x, df$y),]
排序,您可以使用基本R函数split
,lapply
和do.call/rbind
来提取使用&#34; split / apply / combine&#34;方法
do.call(rbind, lapply(split(df, df$x), function(i) i[nrow(i),]))
x y z
1 1 1 a
2 2 1 b
3 3 3 g
5 5 1 c
6 6 1 h
8 8 4 l
split
将data.frame分解为基于x的列表。此列表被送到lapply
,它选择每个data.frame的最后一行,并将这一行data.frames作为列表返回。然后使用rbind
将此列表do.call
编辑到单个数据框中。