2

根据我的最后一个问题,我有一个新的归属问题。编辑我的帖子并在那里询问并等待一周后,我想再次在这里尝试。

这次有一个更好的例子:

Equip<- c(1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,6,6,6)
Notif <-c(1,1,3,4,2,2,2,5,6,7,9,9,15,10,11,12,13,14,16,17,18,19)
rank <- c(1,1,2,3,1,1,1,1,2,3,1,1,2,1,2,3,1,2,3,4,5,6)
Component <- c("Ventil","Motor","Ventil","Ventil","Vergaser","Vergaser","Bremse",
"Lichtmaschine","Bremse","Lichtmaschine","Bremse","Motor","Lichtmaschine",
"Bremse","Bremse","Motor","Vergaser","Motor","Vergaser","Motor",
"Vergaser","Motor")    

df <- data.frame(Equip,Notif,rank,Component)

Equip是我的主题和rank实际访问次数。Component是必须寻找的主题。

我想要这样的输出:

如果 anEquip(subject)被访问了 2 次(rank1 和 2),请使用 1&2 查找所有Equips rank,如果有任何Component被认为是第一次和第二次。

如果 an被所有sEquip(subject)访问 3 次( 1 ,2 和 3 ) ,如果有任何列表 3 次,例如 1, 1, Motor, 1, 2, Motor, 1, 3, MotorrankEquipComponentEquiprankComponentEquiprankComponentEquiprankComponent

输出应具有 的名称Component,例如 True "Motor"

我有一个代码,但是有了这个,我可以比较第 1 次和第 2 次访问,第 2 次和第 3 次访问等等(我不能再次与等级分开,比如装备 2 等级,装备 3 等级等等在)

代码是这样的:

a <- lapply(split(df,df$Equip),function(x){      
ll <- split(x,x$rank)                    
 if(length(ll)>1 )
ii <- intersect(ll[[1]]$Component,ll[[2]]$Component ) ## test intersection
  else 
   ii <- NA
 c(length(ii)> 0 && !is.na(ii),ii)                                              
})
b <- unlist(a)
c <- table(b,b)
rowSums(c)    

希望你能帮助我。请询问是否有任何问题。

根据您关于输出的问题以及您的解决方案,

     Equip Component   V1 idx
1:     1    Ventil  TRUE   3
2:     2        NA  False  1
3:     3        NA  False  3
4:     4        NA  FALSE  2
5:     5        NA  FALSE  3
6:     6        NA  FALSE  6

类似的东西,但如果它更容易,则不一定需要 Equip 和 idx

装备 2 个等级:

TRUE          FALSE
  0             1

装备 3 个等级:

TRUE          FALSE
 1              2

装备 6 个等级:

TRUE          FALSE
 0              1
4

2 回答 2

2

这是我认为您会感兴趣的输出。它使用data.table.

data.table首先,我们从您的data.frame dfwith中创建一个,keys = Equip, Component如下所示。

require(data.table) # load package
# then create the data.table with keys as specified above
# Check that both these columns are already sorted out for you!
dt <- data.table(df, key=c("Equip", "Component"))

其次,我们创建一个函数,该函数将为给定的排名查询(2、3 等)提供所需的输出

this.check <- function(idx) {
    chk <- seq(1, idx)
    o <- subset(dt[, all(chk %in% rank), by=c("Equip", "Component")], V1 == TRUE)
    if (nrow(o) > 0) o[, idx:=idx]
}

这是做什么的?让我们为rank=1,2. 我们通过以下方式运行:

> this.check(2)
# output
   Equip Component   V1 idx
1:     1    Ventil TRUE   2
2:     5    Bremse TRUE   2

这告诉您对于Equip = 1 and 5,分别有Components = Ventil and Bremsewith rank = 1 and 2(用 idx=2 表示)。你也得到了专栏V1 = TRUE,尽管我,正如@Carl 已经指出的那样,不理解这个的必要性。如果需要,可以使用更改此输出的列名setnames

第三,我们使用这个函数来查询ranks=1,2,然后ranks=1,2,3..等等。这可以通过lapply如下简单的方式完成:

# Let's run the function for idx = 2 to 6. 
# This will check from rank = 1,2 until rank=1,2,3,4,5,6
o <- lapply(2:6, function(idx) {
    this.check(idx)
})
> o
[[1]]
   Equip Component   V1 idx
1:     1    Ventil TRUE   2
2:     5    Bremse TRUE   2

[[2]]
   Equip Component   V1 idx
1:     1    Ventil TRUE   3

[[3]]
NULL

[[4]]
NULL

[[5]]
NULL

它表明 forrank=1,2rank=1,2,3你有一些Component. 对于其他人来说,什么都没有= NULL

最后,我们可以将bind所有这些一起使用rbind来获得一个data.table,如下所示:

o <- do.call(rbind, o)
> o
   Equip Component   V1 idx
1:     1    Ventil TRUE   2
2:     5    Bremse TRUE   2
3:     1    Ventil TRUE   3

在这里,idx=2Component满足的rank=1,2idx=3是满足的rank=1,2,3

把它们放在一起:

this.check <- function(idx) {
    chk <- seq(1, idx)
    o <- subset(dt[, all(chk %in% rank), by=c("Equip", "Component")], V1 == TRUE)
    if (nrow(o) > 0) o[, idx:=idx]
}

o <- do.call(rbind, lapply(2:6, function(idx) {
    this.check(idx)
}))

我希望这有帮助。

编辑:(经过一系列评论交流,这是我提出的新解决方案。我希望这就是你所追求的。)

require(data.table)
dt <- data.table(df, key=c("Equip", "Component"))
dt[, `:=`(e.max=max(rank)), by=Equip]
dt[, `:=`(ec.max=max(rank)), by=c("Equip", "Component")]
setkey(dt, "e.max", "ec.max")
this.check <- function(idx) {
    t1 <- dt[J(idx,idx)]
    t2 <- t1[, identical(as.numeric(seq_len(idx)), as.numeric(rank)), 
              by=c("Equip", "Component")]
    o <- table(t2$V1)
    if (length(o) == 1) 
        o <- c(o, "TRUE"=0)
    o <- c("idx"=idx, o)
}
o <- do.call(rbind, lapply(2:6, function(idx) this.check(idx)))

> o
#      idx FALSE TRUE
# [1,]   2     1    0
# [2,]   3     2    1
# [3,]   4     1    0
# [4,]   5     1    0
# [5,]   6     1    0
于 2013-01-17T13:05:52.223 回答
0

如果我将您的数据按列排列为

foo<-cbind(Equip,Notif, rank, Component)
eqp<-1 # later, loop over all values
foo[c( which(  foo[,1]==eqp & (foo[,3]==1 | foo[,3]==2) ) ),4]
[1] "Ventil" "Motor"  "Ventil"

将这些结果输入table并提取 count ==2 的项目

显然,任何出现两次的项目都是您想要的。
这不是我推荐使用的答案,因为类似的工具ddplyaggregate更干净地做到这一点,但我想确保这是你所追求的答案,假设循环遍历eqp原始Equip.

于 2013-01-16T20:30:24.210 回答