我有一个包含多个嵌套在个体内的观察值的数据集。此示例数据集包括ID和星期几(dayweek,1-7)的列。我从每个人的3天中得到的观察结果。因此,一个人可能只提交了有关Sun / Wed / Thu(1、4、5)的报告,而另一个人可能只提交了针对Sun / Mon / Tue(1、2、3、3)的报告,例如以下示例:>
django rest frame work
我想设置一列来标记每个人的第一天,第二天和第三天,就像这样:
df <- data.frame(
id = c(rep(1:2, each = 6),2),
dayweek = c(rep(c(1, 4, 5), each = 2),rep(c(1, 2, 3), each = 2), 3)
)
我尝试使用
df2 <- data.frame(
id = c(rep(1:2, each = 6),2),
dayweek = c(rep(c(1, 4, 5), each = 2),rep(c(1, 2, 3), each = 2), 3),
daynum = c(rep(1:3, each = 2, times = 2), 3)
)
但这会为每个单独的日期组合生成一个新的ID。有什么好方法吗?
谢谢!
答案 0 :(得分:4)
dplyr
将cumsum
和!duplicated
与dplyr
一起使用
df %>%
group_by(id) %>%
mutate(daynum = cumsum(!duplicated(dayweek)))
# A tibble: 13 x 3
# Groups: id [2]
id dayweek daynum
<dbl> <dbl> <int>
1 1 1 1
2 1 1 1
3 1 4 2
4 1 4 2
5 1 5 3
6 1 5 3
7 2 1 1
8 2 1 1
9 2 2 2
10 2 2 2
11 2 3 3
12 2 3 3
13 2 3 3
tapply
来自基础R
unlist(tapply(df$dayweek, df$id, function(x) cumsum(!duplicated(x))))
1 1 2 2 3 3 1 1 2 2 3 3 3
答案 1 :(得分:2)
我们可以group_by
id
并为每个id
创建一个唯一的dayweek
library(dplyr)
df %>%
group_by(id) %>%
mutate(daynum = as.integer(factor(dayweek, levels = unique(dayweek))))
# id dayweek daynum
# <dbl> <dbl> <int>
# 1 1 1 1
# 2 1 1 1
# 3 1 4 2
# 4 1 4 2
# 5 1 5 3
# 6 1 5 3
# 7 2 1 1
# 8 2 1 1
# 9 2 2 2
#10 2 2 2
#11 2 3 3
#12 2 3 3
#13 2 3 3
在基数R中,我们可以使用ave
with(df, ave(dayweek, id, FUN = function(x)
as.integer(factor(x, levels = unique(x)))))
#[1] 1 1 2 2 3 3 1 1 2 2 3 3 3
答案 2 :(得分:0)
根据OP's comment,这些行是按顺序排列的。
然后,这是两种不同的方法,它们也将处理注释中提到的“星期五,星期六,星期日”情况(dayweek
6、7、1)。
rleid()
fct_inorder()
rleid()
这使用了rleid()
包中的data.table
函数:
library(dplyr)
df2 %>%
group_by(id) %>%
mutate(daynum2 = data.table::rleid(dayweek))
id dayweek daynum daynum2 <dbl> <dbl> <dbl> <int> 1 1 1 1 1 2 1 1 1 1 3 1 4 2 2 4 1 4 2 2 5 1 5 3 3 6 1 5 3 3 7 2 1 1 1 8 2 1 1 1 9 2 2 2 2 10 2 2 2 2 11 2 3 3 3 12 2 3 3 3 13 2 3 3 3 14 3 6 1 1 15 3 7 2 2 16 3 1 3 3
请注意,使用的扩展数据集还涵盖了“星期五,星期六,星期日”情况(dayweek
6、7、1)。
fct_inorder()
这是Ronak's answer的增强版本,它也处理“星期五,星期六,星期日”情况。它使用fct_inorder()
包中的forcats
,按首次出现的顺序对因子级别进行重新排序。
df2 %>%
group_by(id) %>%
mutate(daynum2 =
dayweek %>%
as.character() %>%
forcats::fct_inorder() %>%
as.integer()
)
输出与上面相同。
这是一个扩展的数据集,其中还包括“星期五,星期六,星期日”情况(dayweek
6、7、1):
df2 <- data.frame(
id = c(rep(1:2, each = 6), 2, rep(3, 3)),
dayweek = c(rep(c(1, 4, 5), each = 2),rep(c(1, 2, 3), each = 2), 3, 6, 7, 1),
daynum = c(rep(1:3, each = 2, times = 2), 3, 1:3)
)