[英]How to make a new column in a data.frame so that column counts the number of different row in that data.frame?
我有一個像這樣的巨大 data.frame。
首先,如何將新列“date1”添加到此 data.frame 中,以便該列計算此 data.frame 中 UNIQUE 不同日期的數量,然后在該新創建的列中按升序排列。
其次,如何將另一列“date2”添加到此 data.frame 中,以便該列計算一天中不同的 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
我們可以首先使用unite
將year
、 month
和day
成一列,並為該組合的每個組提供唯一編號,然后group_by
相同組合並使用n_distinct
計算每個組合的唯一id
。
library(dplyr)
library(tidyr)
df %>%
unite(date, year, month, day, sep = "-", remove = FALSE) %>%
mutate(date1 = as.integer(factor(date,level = unique(date)))) %>%
group_by(date) %>%
mutate(date2 = n_distinct(id)) %>%
ungroup() %>%
select(-date)
# 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
我們可以在更緊湊做到這一點tidyverse
通過獲取group_indices
在“年”,“月”,“日”的group_by
,然后創建“日期2”作為“身份證”的不同元素的數量( 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
或者這可以通過base R
interaction
和ave
來完成
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))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.