【问题标题】:Comparison under more conditions更多条件下的比较
【发布时间】:2012-12-31 05:59:59
【问题描述】:

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

这次有一个更好的例子:

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 是必须寻找的主题。

我想要这样的输出:

如果 Equip(subject) 被访问了 2 次(rank 1 和 2)查看所有 Equips 和 rank 1&2 ,如果有任何 Component 被认为是第一次和第二次。

如果Equip(subject) 被所有Equips 访问了3 次(rank 1,2 和3),如果有任何Component 列出3 次,例如Equip 1, @ 987654335@ 1, Component 电机, Equip 1, rank 2, Component 电机, Equip 1, rank 3, Component 电机

输出应该具有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

【问题讨论】:

  • 用清楚的话来说是好的。首先,我想查找 2 次访问的 Equips。所以我想要得到的输出是,如果有任何项目(组件)在第一级和第二级监听。如果有这样的项目输出应该是 TRUE 和组件的名称。 3 次访问 装备相同,但应该看看是否有任何组件被用于等级 1,2,3 等......我上面提到的代码,对于寻找没有任何区别2次访问装备,3次访问装备等等..也许现在明白我的意思了吗?

标签: r subset lapply


【解决方案1】:

如果我将你的数据按列排列成一个数组

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 并提取计数 ==2 的项目

显然,任何出现两次的项目都是您想要的。
这不是我推荐使用的答案,因为像 ddplyaggregate 这样的工具会更干净地做到这一点,但我想确保这是你想要的答案,假设循环在 @987654325 @ 原始 Equip 中的值。

【讨论】:

  • 首先,感谢您的回答,我想知道,如果等级 1 中使用的任何项目(在一个装备中)也用于等级 2(在同一装备中),则分析器应该类似于, TRUE 然后是项目的名称。 (对于两次访问的设备(信息访问次数是排名))......然后稍微调整代码,我想获得信息,如果三次访问的设备,排名 1,2, 3 如果有任何项目在每次访问中听。明白我的意思了吗?非常感谢
  • 为什么要使用“TRUE”,因为首先只会返回所需的设备名称?
  • 因为在第一和第二排名中可能有多个组件。所以我在 1 Equip 中有 2 个组件名称。没关系,但我也必须知道装备的数量......你知道我的意思吗?
【解决方案2】:

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

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

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 Bremserank = 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

这表明对于rank=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=2 是满足 rank=1,2Componentidx=3 是满足 rank=1,2,3Component

把它们放在一起:

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

我希望这会有所帮助。

编辑:(在cmets进行了一系列交流后,这是我提出的新解决方案。希望这是您所追求的。)

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

【讨论】:

  • 这非常符合我的需要。因此,如果 Equip 的等级为 1、2、3,那么该组件应该在所有等级中都是相同的组件,否则我的分析会失真。也许为此可以制作具有2个等级的装备子集,然后是具有3个等级的装备等??因为作为我粘贴的代码,我只想读出装备的数量(在这种情况下是真实的)和组件(数量可能更高,因为超过 1 个组件也可能在等级 1 和 2 中)数据集 i我正在处理超过 80k 行,所以我真的需要它,就像我最后所做的那样......
  • 也许你知道别的东西或者建立在你给定的代码上。但到目前为止,我真的非常感谢您的工作 =) 非常感谢
  • 嗯。我会再试一次,因为不知道如何显示所需的输出。也许也可以为具有 2 个等级、具有 3 个等级等的装备拆分数据,然后将它们进行比较,就像在这个拆分的组中是否在每个等级中都有任何相同的组件一样。我的意思是这样的。
  • 我在顶部的第一个问题中根据您的代码编辑了我希望的输出。感谢您的帮助
  • 好的,我们在这里 =) 这就是我的意思。为此非常感谢。我会理解它,也许如果有不清楚的地方,我会问。但此刻,非常感谢您
猜你喜欢
  • 2015-09-15
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多