2

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

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

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

有什么见解可以实现这种比较吗?

谢谢

4

3 回答 3

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)
于 2012-09-04T21:31:29.877 回答
1

这是一个基本的 R 解决方案,假设我正确地遵循了你想要的。foo()是一个比较每个子集中的两个值的函数,而target我们是每个子集中split()的数据。df$xl|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
于 2012-09-04T21:37:11.000 回答
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(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
于 2012-09-04T22:42:16.647 回答