R中的条件子集出错

Conditional subsetting gone wrong in R

所以我在 R 子集化方面遇到了这个相当基本的问题,但因为我是新手,所以我不知道如何正确解决它。我有一些面板数据的例子:

   idnr year  sales space municipality   pop
 1    1 2004 110000  1095          136 71377
 2    1 2005 110000  1095          136 71355
 3    1 2006 110000  1095          136 71837
 4    1 2007 120000  1095          136 72956
 5    2 2004  35000   800          136 71377
 6    3 2004  45000  1000          136 71377
 7    3 2005  45000  1000         2584 23135
 8    3 2006  45000  1000         2584 23258
 9    3 2007  45000  1000         2584 23407
 10   4 2005 180000  5000         2584 23254
 11   4 2006 220000  5000         2584 23135
 12   4 2007 250000  5000         2584 23258

所以我的问题是我想使用 year = 2004 和(不是或)year = 2005 的条件对数据进行子集化。但是它似乎不起作用。代码:

 tab3 <- stores[stores$year==2004 & stores$year==2005, c("idnr","year")]

我想说的是,我需要 select 存在于 2004 年和 2005 年的数据,因为某些条目存在于 2004 年或 2005 年,但两者都不存在,因此应排除在外。以上面的数据为例,这应该是输出:

 idnr year
 1    2004
 1    2005
 3    2004
 3    2005

更新:

我希望 akrun 的方法可能适用于 selecting 数据条目,这些条目仅在 2005 年出现。这样:

 idnr year
 4    2005

不幸的是,事实并非如此。相反,它将 2004 年和 2005 年出现的 idnr 与仅在 2005 年出现的 idnr 分组。有什么想法吗?

如果要使用 year == 2004 year == 2005 进行子集化,则需要使用 | 运算符而不是 & 在你的实际方法中:

tab3 <- stores[stores$year == 2004 | stores$year == 2005, c("idnr", "year")]

结果:

#> tab3
#   idnr year
#1     1 2004
#2     1 2005
#5     2 2004
#6     3 2004
#7     3 2005
#10    4 2005

或使用dplyr:

library(dplyr)
tab3 <- stores %>% select(idnr, year) %>% filter(year == 2004 | year == 2005)

更简洁:

tab3 <- stores %>% select(idnr, year) %>% filter(year %in% c(2004, 2005)) 

这是一个使用 "data.table" 的选项。使用 setDT 将数据集 ("df") 转换为 "data.table"。将 "year" 列设置为 "key" (setkey(..))。子集 "year" 列 (J(c(2004,..)) 中具有“2004/2005”的行,select 前两列 1:2.

library(data.table) # data.table_1.9.5 
DT1 <- setkey(setDT(df),year)[J(c(2004,2005)), 1:2, with=FALSE]
DT1
#    idnr year
#1:    1 2004
#2:    2 2004
#3:    3 2004
#4:    1 2005
#5:    3 2005
#6:    4 2005

更新

根据更新后的预期结果,我们可以检查每个"idnr"组是否有多个唯一的"year"条目(uniqueN(year)>1),得到行索引(.I) 作为列 ("V1") 并子集 data.table "DT1".

 DT1[DT1[, .I[uniqueN(year)>1], idnr]$V1,]
 #     idnr year
 #1:    1 2004
 #2:    1 2005
 #3:    3 2004
 #4:    3 2005

或者所有东西都在一个衬里

setDT(df)[year %in% 2004:2005, if(uniqueN(year) > 1L) year, idnr]
#    idnr   V1
# 1:    1 2004
# 2:    1 2005
# 3:    3 2004
# 4:    3 2005

或者 base R 选项是

 indx <- with(df, ave(year==2004, idnr, FUN=any)& ave(year==2005, 
                     idnr, FUN=any) & year %in% 2004:2005)
 df[indx,1:2]
 #  idnr year
 #1    1 2004
 #2    1 2005
 #6    3 2004
 #7    3 2005

更新2

根据数据集和显示的预期结果,我们可以检查每个组 "idnr" 的 "year" 的第一个值是否为 2005。如果为真,则对第一个观察值 (.SD[1L,..]) 和 select 所需的列进行子集化。

   setDT(df)[,if(year[1L]==2005) .SD[1L,1,with=FALSE], by = idnr]
   #   idnr year
   #1:    4 2005

   setDT(df)[df[,.I[year[1L]==2005] , by = idnr]$V1[1L], 1:2, with=FALSE]
   #   idnr year
   #1:    4 2005