【问题标题】:Count how many observations fall between start, end values that vary by group计算在开始值和结束值之间有多少观察值因组而异
【发布时间】:2020-05-22 21:37:33
【问题描述】:

如何创建按 id 变量分组的开始年份和结束年份之间有多少活动观察的计数?

我有一个 df,其分析单位是组织。这些组织仅在特定时间段(startyear、endyear)和特定国家(acr)活跃。一些国家有不止一个组织同时活跃。我想创建一个变量来反映每个国家/地区同时活跃的组织数量(对于每个观察结果,答案至少为 1,可能是几十个)。对于每个观察的起始年,我相信我需要按国家/地区检查我的数据框,并计算起始年在其他观察起始年/结束年之间的次数。怎么做?

我已尝试使用 dplyr 执行此操作(根据 Count how many fall in each group in R):

nsa2 <- nsa %>%
  group_by(acr,startyear) %>%
  mutate(count=n())

有没有办法使用 filter() 或 between(),即使年份之间不是固定的而是变化的?甚至申请回去过df?

以下是一些示例数据,其中有一些重叠的 obs:

structure(list(acr = structure(c(8L, 10L, 11L, 7L, 6L, 4L, 7L, 
6L, 3L, 3L, 12L, 2L, 13L, 9L, 1L, 8L, 15L, 7L, 5L, 14L), .Label = c("AFG", 
"ARG", "CHA", "DRC", "IRQ", "ISR", "MYA", "RUS", "RWA", "SOM", 
"SUD", "THI", "UKG", "YUG", "ZIM"), class = "factor"), startyear = c(1994, 
2009, 1971, 1996, 1965, 2008, 2000, 1990, 1992, 1992, 2003, 1974, 
1957, 1997, 1996, 1946, 1976, 1996, 2004, 1998), endyear = c(1996, 
2010, 1971, 1996, 1973, 2008, 2000, 1999, 1994, 1994, 2011, 1977, 
1957, 2002, 1996, 1948, 1979, 1996, 2005, 1999), obsid = structure(c(5L, 
3L, 19L, 6L, 11L, 10L, 20L, 9L, 17L, 18L, 8L, 12L, 14L, 4L, 2L, 
16L, 1L, 13L, 15L, 7L), .Label = c("NSA.3.4-1030", "NSA.3.4-1126", 
"NSA.3.4-1219", "NSA.3.4-1381", "NSA.3.4-1546", "NSA.3.4-157", 
"NSA.3.4-1594", "NSA.3.4-1657", "NSA.3.4-1666", "NSA.3.4-1678", 
"NSA.3.4-271", "NSA.3.4-346", "NSA.3.4-376", "NSA.3.4-391", "NSA.3.4-406", 
"NSA.3.4-58", "NSA.3.4-679", "NSA.3.4-685", "NSA.3.4-892", "NSA.3.4-91"
), class = "factor")), row.names = c(NA, -20L), groups = structure(list(
    acr = structure(c(1L, 4L, 15L, 26L, 43L, 44L, 44L, 59L, 59L, 
    75L, 75L, 77L, 83L, 87L, 91L, 97L, 104L, 105L), .Label = c("AFG", 
    "ALG", "ANG", "ARG", "AZE", "BFO", "BNG", "BOL", "BOS", "BUI", 
    "CAM", "CAO", "CDI", "CEN", "CHA", "CHL", "CHN", "COL", "COM", 
    "CON", "COS", "CRO", "CUB", "DJI", "DOM", "DRC", "EGY", "ERI", 
    "ETH", "FRN", "GAB", "GAM", "GHA", "GNB", "GRC", "GRG", "GUA", 
    "GUI", "HAI", "IND", "INS", "IRN", "IRQ", "ISR", "KEN", "LAO", 
    "LBR", "LEB", "LES", "LIB", "MAA", "MAC", "MAG", "MAL", "MEX", 
    "MLD", "MLI", "MOR", "MYA", "MZM", "NEP", "NIC", "NIG", "NIR", 
    "NTH", "OMA", "PAK", "PAN", "PAR", "PER", "PHI", "PNG", "POR", 
    "RUM", "RUS", "RVN", "RWA", "SAF", "SAL", "SAU", "SEN", "SIE", 
    "SOM", "SPN", "SRI", "SSD", "SUD", "SUR", "SYR", "TAJ", "THI", 
    "TOG", "TRI", "TUN", "TUR", "UGA", "UKG", "URU", "USA", "UZB", 
    "VEN", "YEM", "YPR", "YUG", "ZIM"), class = "factor"), startyear = c(1996, 
    1974, 1992, 2008, 2004, 1965, 1990, 1996, 2000, 1946, 1994, 
    1997, 2009, 1971, 2003, 1957, 1998, 1976), .rows = list(15L, 
        12L, 9:10, 6L, 19L, 5L, 8L, c(4L, 18L), 7L, 16L, 1L, 
        14L, 2L, 3L, 11L, 13L, 20L, 17L)), row.names = c(NA, 
-18L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

【问题讨论】:

  • 不清楚您的期望。你要nsa %&gt;% group_by(acr) %&gt;% filter(all(startyear &lt; endyear))

标签: r dplyr


【解决方案1】:

也许这会给你一些想法

check_overlap <- function(start,end){
  map2_dbl(start,end, ~sum((.x >= start & .x <= end) | (.y <= end & .y >= start)  )) 

}
nsa %>% 
  group_by(acr) %>% 
  mutate(overlap = check_overlap(startyear, endyear)) %>% 
  arrange(acr)

希望这会有所帮助!

【讨论】:

  • 我认为这可以解决问题!仍在尝试了解 map2_dbl() 正在做什么,但非常感谢您的帮助。
  • map2_dbl 是 purrr 包中的一个函数。它类似于 sapply,但迭代了 2 个列表或向量。
【解决方案2】:

我们可以试试

library(dplyr)
nsa %>% 
   group_by(acr) %>%
   filter(all(startyear < endyear))

【讨论】:

    猜你喜欢
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2016-08-12
    • 2020-07-13
    • 1970-01-01
    相关资源
    最近更新 更多