我的数据格式如下
name date x y z
a March-2018 1 2 2
a Feb-2018 2 3 3
b June-2017 3 4 4
b April-2017 4 5 5
c Sep-2018 5 5 6
c Aug-2017 7 7 8
需要根据以下最新月份选择名称和其他列。
name date x y z
a March-2018 1 2 2
b June-2017 3 4 4
c Sep-2018 5 5 6
我尝试使用不同的名称并选择了最大日期,但没有锻炼。
答案 0 :(得分:1)
我们通过粘贴任意日期(“ 01”),然后粘贴date
group_by
,将name
列转换为实际日期列,并获得max
行。 / p>
library(dplyr)
df %>%
mutate(newdate = as.Date(paste0("01-", date), "%d-%b-%Y")) %>%
group_by(name) %>%
slice(which.max(newdate)) %>%
select(-newdate)
# name date x y z
# <fct> <fct> <int> <int> <int>
#1 a March-2018 1 2 2
#2 b June-2017 3 4 4
#3 c Sep-2018 5 5 6
使用ave
的基本R选项,我们首先转换日期,然后按组(max
)获取name
日期,并从原始数据帧中将其子集化。
df$new_date <- as.Date(paste0("01-", df$date), "%d-%b-%Y")
#I was trying to use which.max instead of max but it giving me an error, not sure why
df[with(df, new_date %in% ave(new_date, name, FUN = max)), ]
# name date x y z new_date
#1 a March-2018 1 2 2 2018-03-01
#3 b June-2017 3 4 4 2017-06-01
#5 c Sep-2018 5 5 6 2018-09-01
注意-正如@ IceCreamToucan所提到的,ave
方法在这里起作用是因为每个name
都有不同的max
date
,如果日期相同,则由于我们在这里使用%in%
。
答案 1 :(得分:1)
您可以使用tidyverse
:
df %>%
mutate(temp = match(gsub("-.*$", "", date), month.abb),
temp2 = ifelse(is.na(temp), match(gsub("-.*$", "", date), month.name), temp)) %>%
group_by(name) %>%
filter(temp2 == max(temp2)) %>%
select(-starts_with("temp"))
name date x y z
<fct> <fct> <int> <int> <int>
1 a March-2018 1 2 2
2 b June-2017 3 4 4
3 c Sep-2018 5 5 6
首先,它从“日期”中取出月份名称,然后为缩写月份名称分配一个数字,其中1月为1,12月为12。其次,它为非缩写月份名称分配一个数字。第三,它筛选出每组中分配给月份最多的行。最后,它删除了多余的变量。
答案 2 :(得分:0)
以下是使用group_by
和slice
和split
在基座中复制lapply
和[
的一种round回方式。
do.call(rbind,
lapply(split(df, df$name),
function(x) x[which.max(as.Date(paste0("01-", x$date), "%d-%b-%Y")),])
)
# name date x y z
# a a March-2018 1 2 2
# b b June-2017 3 4 4
# c c Sep-2018 5 5 6
另一个选择是先aggregate
,然后再merge
。似乎在我遗失的基础上,可能还有其他更简单的方法可以做到这一点。
to.keep <-
aggregate(date ~ name, data = df,
function(x) x[which.max(as.Date(paste0("01-", x), "%d-%b-%Y"))])
merge(df, to.keep, by = names(to.keep))
# name date x y z
# a a March-2018 1 2 2
# b b June-2017 3 4 4
# c c Sep-2018 5 5 6
使用的数据
structure(list(name = c("a", "a", "b", "b", "c", "c"), date = c("March-2018",
"Feb-2018", "June-2017", "April-2017", "Sep-2018", "Aug-2017"
), x = c(1L, 2L, 3L, 4L, 5L, 7L), y = c(2L, 3L, 4L, 5L, 5L, 7L
), z = c(2L, 3L, 4L, 5L, 6L, 8L)), row.names = c(NA, -6L), class = "data.frame")