比较基于子集的两个字符

时间:2012-09-04 21:21:56

标签: r plyr

我有一个包含两列的简单数据框:

df <- data.frame(x = c(1,1,2,2,3), 
                 y = c(rep(1:2,2),1), 
                 target = c('a','a','a','b','a'))

我想在x的每个级别(x的相同数字)内比较目标列中的字符串(找出它们是否相等,即TRUE或FALSE)。 首先,我想比较第1和第2行,然后是3和4 ...... 我的问题是我缺少一些比较,例如,第5行只有一个案例而不是两个 - 所以它应该变成FALSE。 变量y表示x中的第一个和第二个案例。

我玩ddply做了类似的事情:

ddply(df, .(x), summarise,
        ifelse(as.character(df[df$y == '1',]$target), 
               as.character(df[df$y == '2',]$target),0,1))

这是丑陋的...... 并且不起作用......

有什么见解如何实现这种比较?

由于

3 个答案:

答案 0 :(得分:1)

ddply(df, .(x), function(d) NROW(d) == 2 & d$target[1] == d$target[2])

假设只有恰好有2行具有“x”值时才希望该值为TRUE。如果有可能有3个或更多,并且如果所有target值相同,您希望它为TRUE,您可以这样做:

ddply(df, .(x), function(d) NROW(d) > 1 & length(unique(d$target)) == 1)

答案 1 :(得分:1)

这是一个基本的R解决方案,假设我已经按照你想要的正确方法。 foo()是一个比较每个子集中两个target值的函数,而我们split()df$x l|sapply()上的数据foo()的子集。

foo <- function(x) {
    with(x, {if(length(target) < 2) {
                 FALSE
             } else {
                 isTRUE(all.equal(target[1], target[2]))
             }})
}
lapply(split(df, df$x), foo)

sapply(split(df, df$x), foo)

产生此输出

> lapply(split(df, df$x), foo)
$`1`
[1] TRUE

$`2`
[1] FALSE

$`3`
[1] FALSE

> 
> sapply(split(df, df$x), foo)
    1     2     3 
 TRUE FALSE FALSE

答案 2 :(得分:1)

 ave(as.character(df$target), df$x, 
     FUN=function(z) if ( length(z)=="2" & length(unique(z))==1){TRUE} else{ FALSE })
[1] "TRUE"  "TRUE"  "FALSE" "FALSE" "FALSE"

或者......如果您只想按组...结果,请使用aggregate:

>  aggregate(as.character(df$target), list(df$x), 
+      FUN=function(z) if ( length(z)=="2" & length(unique(z))==1){TRUE} else{ FALSE })
  Group.1     x
1       1  TRUE
2       2 FALSE
3       3 FALSE