选择具有指定列属性的ID

时间:2011-10-25 11:13:56

标签: r

我尝试进行选择的数据看起来像是

   ID Field  Rank
8    6 Other  Prof
9    6 Other  Prof
13   7 Other Assoc
16   7 Other Assoc
17   7 Other  Prof
18   8 Other Assoc
19   8 Other Assoc
22   9 Other Assoc
23   9 Other Assoc
24   9 Other  Prof

我正在尝试创建一个新变量,其中包含已从“Assoc”升级为“Prof”的人员(ID)的所有行。例如,我希望我的新变量看起来像

   ID Field  Rank
13   7 Other Assoc
16   7 Other Assoc
17   7 Other  Prof
22   9 Other Assoc
23   9 Other Assoc
24   9 Other  Prof

我尝试了子集功能,但没有运气。

R中是否有可以执行此操作的功能?如果没有,怎么能实现这一目标。

编辑:这里是dput()的结果。注意我省略了“Field”变量,因为它在此示例中不包含任何信息。

 df.promotion <- structure(list(id = c(6, 6, 7, 7, 7, 8, 8, 9, 9, 9), rank = structure(c(2L, 
 2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 2L), .Label = c("Assoc", "Prof"
 ), class = "factor")), .Names = c("id", "rank"), row.names = c(NA, 
 -10L), class = "data.frame")

4 个答案:

答案 0 :(得分:4)

您可以使用xtabsIDRank列出数据表格:

tab <- xtabs(~ID+Rank,dfr)
tab
   Rank
ID  Assoc Prof
  6     0    2
  7     2    1
  8     2    0
  9     2    1

你想要没有零的那些:

subset(dfr,ID %in% rownames(tab[as.logical(apply(tab,1,prod)),]))
   ID Field  Rank
13  7 Other Assoc
16  7 Other Assoc
17  7 Other  Prof
22  9 Other Assoc
23  9 Other Assoc
24  9 Other  Prof

答案 1 :(得分:2)

这是一个相当容易理解的方法,它使用您的第一个倾向使用subset()执行此操作:

我创建了p,这是所有教授的id。然后我创建了a,这是每个人的合作伙伴。然后使用%in%我们选择所有同时属于Assoc和Prof.的人。这给了我一组密钥,然后我可以使用它来对初始data.frame进行子集化。

p <- unique(subset(df.promotion, rank=="Prof")$id)
a <- unique(subset(df.promotion, rank=="Assoc")$id)

mySet <- a[a %in% p]
subset(df.promotion, id %in% mySet)

答案 2 :(得分:1)

让我们用基数R来做(尽管plyr正在招手): 编辑改编+测试新提供的dput输出...

dfr<-df.promotion #just so I don't have to change too much below
colnames(dfr)<-c("ID", "Rank") #just so I don't have to change too much below
promotedIDs<-unique(dfr$ID)[sapply(unique(dfr$ID), function(curID){
  hasBoth<-(sum(is.na(match(c("Assoc", "Prof"), dfr$Rank[dfr$ID==curID]))) == 0)
})]
result<-dfr[dfr$ID %in% promotedIDs,]

我用match检查“Prof”和“Assoc”是否都在每个ID的Rank列表中。请注意,如果找不到值,则match会返回NA,因此计算NA的数量可以找出两者是否匹配。

答案 3 :(得分:1)

以下是使用plyr的惯用单线程。该代码的工作原理是:(a)按ID拆分数据框,以及(b)仅选择具有大于1个唯一等级的subsets(这是促销的代理)

require(plyr)
ddply(df.promotion, .(id), subset, length(unique(rank)) > 1)