我尝试进行选择的数据看起来像是
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")
答案 0 :(得分:4)
您可以使用xtabs
按ID
和Rank
列出数据表格:
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)