如何在data.table中筛选拥有两个年份数据的国家观测值
解决data.table筛选多年份国家观测的问题
嘿,我来帮你搞定这个筛选问题~你想要保留那些有至少两个不同年份数据的国家,剔除像BEL这种只有单一年份的观测,之前的代码出错是因为逻辑判断和语法位置的问题,我给你拆解下:
先说说你之前代码的问题
- 第一个代码
DT[,if(unique(year)>1) .SD, by=country]:这里的unique(year)返回的是该国家的所有年份向量(比如BEL是c(2002),NLD是c(2002,2006)),你用>1是在和数值1比较年份大小,而不是判断年份的数量是否大于1,逻辑完全错啦。 - 第二个代码
DT[unique(year)>1, .SD, by=country]:data.table的i位置是按行的逻辑筛选,而unique(year)是每个组的唯一年份集合,长度和组内行数不匹配,所以才会报长度不匹配的错误,这是data.table为了避免bug禁止循环回收逻辑向量导致的。
正确的解决方案
这里有两种高效的方法,都能得到你想要的结果:
方法1:分组后直接筛选(简洁直观)
用data.table的uniqueN()函数(专门计算唯一值数量,比length(unique())更快),分组后判断每个国家的唯一年份数是否大于1,是的话保留该组所有行:
DT[, if (uniqueN(year) > 1) .SD, by = country]
方法2:先获取有效国家再筛选(大数据集更高效)
先提取所有符合条件的国家列表,再用这个列表去原数据筛选,这种方法在数据量大的时候性能更好:
# 第一步:计算每个国家的唯一年份数,筛选出年份数>1的国家 valid_countries <- DT[, .(n_years = uniqueN(year)), by = country][n_years > 1, country] # 第二步:保留这些国家的所有观测 DT[country %in% valid_countries]
验证结果
运行上面任意一段代码,都会得到你期望的输出:
ID country year Event_A Event_B 1: 6 NLD 2002 1 1 2: 7 NLD 2006 1 0 3: 8 NLD 2006 1 1 4: 9 GBR 2001 0 1 5: 10 GBR 2001 0 0 6: 11 GBR 2001 0 1 7: 12 GBR 2007 1 1 8: 13 GBR 2007 1 1
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

