只需要通过在R中对数据帧的两列进行分组来获取前两个最高的记录
我有一个data.frame,它包含4列13行。下面是示例数据。[列名为大写,数据为小写] 示例输入数据:只需要通过在R中对数据帧的两列进行分组来获取前两个最高的记录,r,dataframe,R,Dataframe,我有一个data.frame,它包含4列13行。下面是示例数据。[列名为大写,数据为小写] 示例输入数据: NAME. MARKS MONTH COUNTRY ram 20. jan India ranjith 40. jan India naren. 80. jan. India Amir. 90. feb. India kumar. 60. feb India azhar 80. feb India mark
NAME. MARKS MONTH COUNTRY
ram 20. jan India
ranjith 40. jan India
naren. 80. jan. India
Amir. 90. feb. India
kumar. 60. feb India
azhar 80. feb India
mark 90. feb. US
Alex. 55 feb. US
chris 20 feb US
rakesh 60. jan US
Mona. 70. jan. US
mano. 90. mar. UK
Ron. 37. mar. UK
预期产出:
NAME MARKS. MONTH COUNTRY
naren 80. jan. India
ranjith 40. jan. India
Amir. 90. feb. India
Azhar. 80. feb. India
mark. 90. feb. US
Alex 55. feb. US
Mona. 70. jan. US
Rakesh. 60. jan. US
mano. 90. mar. UK
Ron. 37. mar. UK
问题:从输入数据框中,我只想从每个名为“月”和“国家”的组中选择最高的两个标记值。上面给出了示例输出
任何人都可以共享示例代码以生成正确的输出并将其分配给新的数据帧。包括sqldf在内的任何方法都是可取的。您可以使用data.table如下所示。感谢@Arun对改进答案的建议
require(data.table)
dat <- fread(txt)
dat[order(MARKS), tail(.SD, 2L), by=c("MONTH", "COUNTRY")]
这导致:
MONTH COUNTRY NAME MARKS
1: jan India ranjith 40
2: jan India naren 80
3: feb India kumar 60
4: feb India azhar 80
5: feb US Alex 55
6: feb US chris 20
7: feb India rakesh 60
8: feb India Mona 70
9: mar UK mano 90
10: mar UK Ron 37
其中txt是不带结尾的数据
在dplyr中,您可以按分组、排列和切片。进行一些清洁:
library(dplyr)
# take out .s
df %>% mutate_all(sub, pattern = '.', replacement = '', fixed = TRUE) %>%
# convert to numbers, if necessary
mutate_all(type.convert, as.is = TRUE) %>%
# set grouping for following operations
group_by(MONTH, COUNTRY) %>%
# sort by MARKS, descending
arrange(desc(MARKS)) %>%
# subset to top two rows of each group
slice(1:2)
## Source: local data frame [10 x 4]
## Groups: MONTH, COUNTRY [5]
##
## NAME. MARKS MONTH COUNTRY
## <chr> <int> <chr> <chr>
## 1 Amir 90 feb India
## 2 azhar 80 feb India
## 3 mark 90 feb US
## 4 Alex 55 feb US
## 5 naren 80 jan India
## 6 ranjith 40 jan India
## 7 Mona 70 jan US
## 8 rakesh 60 jan US
## 9 mano 90 mar UK
## 10 Ron 37 mar UK
这是一个没有使用包的基本R选项。我们使用substr从“月”中提取前3个字母,因为其中有一些字母。在某些情况下。使用ave,我们根据“国家”和“月份”分组后的排名得到逻辑索引,它可以用来子集行
df1$MONTH <- substr(df1$MONTH, 1, 3)
df1[with(df1, as.logical(ave(MARKS, COUNTRY, MONTH,
FUN = function(x) rank(-x) %in% 1:2))),]
除非它们是一致的,否则你的.s会把分组搞得一团糟。另外,它使你的数字看起来可能是字符串,而不是实际的数字。Alistaire..我手动输入的那些数字没有粘贴。所以请忽略输入错误。把这些数字当作“忽略”,谢谢你的回应,上面的代码也会生成名字列吗?因为我的输出需要全部4列。我不确定数据是否按照tail选择正确行的顺序排序。现在,我认为这是正确的继续=分数。。。这是错的吗?它应该按标记排序,然后按=…@Arun分组,谢谢你的评论。因此,也许我确实理解了一些错误:setkey keys=对data.table进行排序。二级索引应该在没有排序的情况下执行类似的操作。因此,我如何在运行中对数据进行排序。例如,表按标记排序,然后按=。。。。因此,j.e.g.SD中的数据按标记排序,并按。。。我认为这也是on可以使用的。所以Arun建议的代码将用于此问题?使用order函数根据标记进行排序,然后使用fiven tail函数仅拾取最后2个值,然后使用2列c进行分组。请确认once@Arun:谢谢你的解释。刚刚编辑了答案。谢谢Alistaire..我会实施它并与您分享详细信息..我会随时通知您
library(dplyr)
# take out .s
df %>% mutate_all(sub, pattern = '.', replacement = '', fixed = TRUE) %>%
# convert to numbers, if necessary
mutate_all(type.convert, as.is = TRUE) %>%
# set grouping for following operations
group_by(MONTH, COUNTRY) %>%
# sort by MARKS, descending
arrange(desc(MARKS)) %>%
# subset to top two rows of each group
slice(1:2)
## Source: local data frame [10 x 4]
## Groups: MONTH, COUNTRY [5]
##
## NAME. MARKS MONTH COUNTRY
## <chr> <int> <chr> <chr>
## 1 Amir 90 feb India
## 2 azhar 80 feb India
## 3 mark 90 feb US
## 4 Alex 55 feb US
## 5 naren 80 jan India
## 6 ranjith 40 jan India
## 7 Mona 70 jan US
## 8 rakesh 60 jan US
## 9 mano 90 mar UK
## 10 Ron 37 mar UK
df1$MONTH <- substr(df1$MONTH, 1, 3)
df1[with(df1, as.logical(ave(MARKS, COUNTRY, MONTH,
FUN = function(x) rank(-x) %in% 1:2))),]