【问题标题】:Conditional subsetting gone wrong in RR中的条件子集出错了
【发布时间】:2015-02-02 03:05:12
【问题描述】:

所以我在 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

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

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

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

 idnr year
 1    2004
 1    2005
 3    2004
 3    2005

更新:

我希望 akrun 的方法可以用于选择仅在 2005 年出现的数据条目。这样:

 idnr year
 4    2005

不幸的是,它没有。相反,它将 2004 年和 2005 年出现的 idnr 与仅在 2005 年出现的 idnr 组合在一起。有什么想法吗?

【问题讨论】:

  • 您不能同时拥有 2004 和 2005。您可以拥有 2004 或 2005。
  • 多么不幸,因为我需要根据是否在 2004 年和 2005 年从整个列表中选择数据。因为有些条目只存在于 2004 年或 2005 年 - 这不够了。
  • 这就是为什么你需要按照下面的回答做:使用|而不是&amp;
  • 使用 |而是包括 2004 年存在但 2005 年不存在的值以及其他方式(2005 年存在,但 2004 年不存在)。我想要做的是它子集 2004 年和 2005 年都存在的数据。
  • 所以你的第一个陈述根本不清楚。

标签: r subset


【解决方案1】:

这是一个使用“data.table”的选项。使用setDT 将数据集(“df”)转换为“data.table”。将“年份”列设置为“键”(setkey(..))。将“年”列 (J(c(2004,..)) 中包含“2004/2005”的行子集,选择前两列 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”组是否有多个唯一的“年份”条目(uniqueN(year)&gt;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。如果为 TRUE,则子集第一个观察 (.SD[1L,..]) 并选择所需的列。

   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

【讨论】:

  • 类似的东西,但它仍然包含仅在 2005 年才开始存在的数据条目。
  • 我已经包含了我的预期输出。希望澄清
  • @DavidArenburg 我不明白你为什么删除你的答案。我只是在称赞您的解决方案。
  • 因为和你的太像了
  • @akrun 我已经用其他问题更新了问题。我尝试将您的解决方案与不同的逻辑运算符一起使用,但它似乎没有产生所需的输出。有什么想法吗?
【解决方案2】:

如果您想使用year == 2004 year == 2005 进行子集化,您需要在实际方法中使用| 运算符而不是&amp;

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)) 

【讨论】:

  • stores$year %in% c(2004, 2005) 可以节省一些输入
  • 这如何回答这个问题? OP 不想只过滤 2004 年和 2005 年。同样如前所述,%in% 也可以,但我认为这不能解决实际问题
  • @DavidArenburg:这是在回答 OP 最初的问题。我不知道您是否注意到,但 OP 中有 2 个重大更新。我只是没有时间跟进并更新答案(我的答案实际上处于 akrun 第一枪的状态)。正如 Pascal 在 cmets 中提到的,第一个陈述根本不清楚。
猜你喜欢
  • 1970-01-01
  • 2018-04-23
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 2022-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多