我有一个包含两列的简单数据框:
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))
这是丑陋的...... 并且不起作用......
有什么见解如何实现这种比较?
由于
答案 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