我的数据框看起来像这样
library(dplyr)
test.df <- data.frame(id=c(1,1,1,3,3,3,3),
date=c("2016-02-13","2016-06-01",
"2016-09-01","2015-08-02",
"2015-09-21","2016-12-01",
"2017-02-11"))
test.df$date <- as.Date(test.df$date,format='%Y-%m-%d')
id date
1 2016-02-13
1 2016-06-01
1 2016-09-01
3 2015-08-02
3 2015-09-21
3 2016-12-01
3 2017-02-11
我想创建一个新变量first.login
以获取每个id
的第一个日期。输出将如下所示
id date first.login
1 2016-02-13 2016-02-13
1 2016-06-01 2016-02-13
1 2016-09-01 2016-02-13
3 2015-08-02 2015-08-02
3 2015-09-21 2015-08-02
3 2016-12-01 2015-08-02
3 2017-02-11 2015-08-02
我尝试使用像这样的代码
new.df <- test.df %>%
group_by(id) %>%
mutate(first.log = min(date))
但是这会得到的结果是提取整个数据框的最早日期,而不是每个ID组。
id date first.login
1 2016-02-13 2015-08-02
1 2016-06-01 2015-08-02
1 2016-09-01 2015-08-02
3 2015-08-02 2015-08-02
3 2015-09-21 2015-08-02
3 2016-12-01 2015-08-02
3 2017-02-11 2015-08-02
这不应该是一个棘手的任务,但我想知道我犯了什么错误?我怎样才能在每个id
小组中获得最早的内容?
更新:
我之前尝试过summarize
,
new.df <- test.df %>%
group_by(id) %>%
summarize(first.login = min(date))
但它返回一行和一列。
first.log
2015-08-02
这些代码没有任何问题;我只需要在其中指定dplyr::mutate
。
答案 0 :(得分:3)
您想使用summary而不是mutate
new.df <- test.df %>%
group_by(id) %>%
summarize(first.log = min(date))
答案 1 :(得分:2)
这是一个循序渐进的R基础解决方案:
# renaming for easy handle
x <- test.df$date
g <- test.df$id
# getting min
split(x, g) <- lapply(split(x, g), min)
# merging
test.df$first.login <- do.call("c", split(x, g))
#printting result
test.df
id date first.login
1 1 2016-02-13 2016-02-13
2 1 2016-06-01 2016-02-13
3 1 2016-09-01 2016-02-13
4 3 2015-08-02 2015-08-02
5 3 2015-09-21 2015-08-02
6 3 2016-12-01 2015-08-02
7 3 2017-02-11 2015-08-02
实际上这就是ave
在
答案 2 :(得分:1)
每当你需要每行一个结果,而不是每组只需要一个值时,你应该使用基本R函数ave
。
test.df$first.login <- ave(test.df$date, test.df$id, FUN = min)
test.df
# id date first.login
#1 1 2016-02-13 2016-02-13
#2 1 2016-06-01 2016-02-13
#3 1 2016-09-01 2016-02-13
#4 3 2015-08-02 2015-08-02
#5 3 2015-09-21 2015-08-02
#6 3 2016-12-01 2015-08-02
#7 3 2017-02-11 2015-08-02