我有一个像这样的巨大data.frame。
首先,如何在此data.frame中添加新列“ date1”,以便该列计算此data.frame中不同天的唯一天数,然后在该新创建的列中以升序排列。
第二,如何在此data.frame中添加另一列“ date2”,以使该列在一天内计算不同ID的总和?
year month day id
2011 1 5 31
2011 1 14 22
2011 2 6 28
2011 2 17 41
2011 3 9 55
2011 1 5 34
2011 1 14 25
2011 2 6 36
2011 2 17 11
2011 3 12 10
我期望的结果看起来像这样。请帮忙!
year month day id date1 date2
2011 1 5 31 1 2
2011 1 14 22 2 2
2011 2 6 28 3 2
2011 2 17 41 4 2
2011 3 9 55 5 1
2011 1 5 34 1 2
2011 1 14 25 2 2
2011 2 6 36 3 2
2011 2 17 11 4 2
2011 3 12 10 6 1
答案 0 :(得分:1)
我们首先可以使用year
将month
,day
和unite
合并为一列,并为该组合的每个组指定一个唯一的编号,然后{{1} }相同的组合,并使用group_by
为每个组合计算唯一的id
。
n_distinct
答案 1 :(得分:1)
我们可以在tidyverse
中更紧凑地执行此操作,方法是在group_indices
中获取“年”,“月”,“天”的group_by
,然后将“ date2”创建为'id'(n_distinct
)的不同元素的数量
librarytidyverse)
df1 %>%
group_by(date1 = group_indices(., year, month, day)) %>%
mutate(date2 = n_distinct(id))
# A tibble: 10 x 6
# Groups: date1 [6]
# year month day id date1 date2
# <int> <int> <int> <int> <int> <int>
# 1 2011 1 5 31 1 2
# 2 2011 1 14 22 2 2
# 3 2011 2 6 28 3 2
# 4 2011 2 17 41 4 2
# 5 2011 3 9 55 5 1
# 6 2011 1 5 34 1 2
# 7 2011 1 14 25 2 2
# 8 2011 2 6 36 3 2
# 9 2011 2 17 11 4 2
#10 2011 3 12 10 6 1
或另一个带有data.table
的紧凑型选项(使用相同的逻辑)
library(data.table)
setDT(df1)[, date1 := .GRP, .(year, month, day)][, date2 := uniqueN(id), date1][]
# year month day id date1 date2
# 1: 2011 1 5 31 1 2
# 2: 2011 1 14 22 2 2
# 3: 2011 2 6 28 3 2
# 4: 2011 2 17 41 4 2
# 5: 2011 3 9 55 5 1
# 6: 2011 1 5 34 1 2
# 7: 2011 1 14 25 2 2
# 8: 2011 2 6 36 3 2
# 9: 2011 2 17 11 4 2
#10: 2011 3 12 10 6 1
或者可以使用interaction
中的ave
和base R
来完成
df1$date1 <- with(df1, as.integer(interaction(year, month, day,
drop = TRUE, lex.order = TRUE)))
df1$date2 <- with(df1, ave(id, date1, FUN = function(x) length(unique(x))))
df1 <- structure(list(year = c(2011L, 2011L, 2011L, 2011L, 2011L, 2011L,
2011L, 2011L, 2011L, 2011L), month = c(1L, 1L, 2L, 2L, 3L, 1L,
1L, 2L, 2L, 3L), day = c(5L, 14L, 6L, 17L, 9L, 5L, 14L, 6L, 17L,
12L), id = c(31L, 22L, 28L, 41L, 55L, 34L, 25L, 36L, 11L, 10L
)), class = "data.frame", row.names = c(NA, -10L))