我有四个逻辑向量数据帧,V1,V2,V3,V4是TRUE或FALSE。我需要基于布尔向量的组合(例如,“无”,“V1只有”,“V1和V3”,“全部”等数据帧的每一行进行分类)。我想这样做,而不采取数据框的子集或嵌套ifelse语句。 任何建议最好的方法来做到这一点?谢谢!比较布尔向量
Q
比较布尔向量
4
A
回答
3
看起来我已经到达在这次晚会上已经很晚了。尽管如此,我仍然可以分享我带来的东西!
这通过处理FALSE/TRUE
可能性等位,并在其上操作分配给的v1
,v2
每个组合,和v3
1和8(很像chmod
可以表示上*NIX
系统权限位)之间的唯一整数。该整数然后用作索引来选择文本描述符向量的适当元素。
(对于演示,我用短短三列,但这种方法很好地扩展了。)
# CONSTRUCT VECTOR OF DESCRIPTIONS
description <- c("None", "v1", "v2", "v1 and v2",
"v3", "v1 and v3", "v2 and v3", "All")
# DEFINE DESCRIPTION FUNCTION
getDescription <- function(X) {
index <- 1 + sum(X*c(1,2,4))
description[index]
}
# TRY IT OUT ON ALL COMBOS OF v1, v2, and v3
df <- expand.grid(v1=c(FALSE, TRUE),
v2=c(FALSE, TRUE),
v3=c(FALSE, TRUE))
df$description <- apply(df, 1, getDescription)
# YEP, IT WORKS.
df
# v1 v2 v3 description
# 1 FALSE FALSE FALSE None
# 2 TRUE FALSE FALSE v1
# 3 FALSE TRUE FALSE v2
# 4 TRUE TRUE FALSE v1 and v2
# 5 FALSE FALSE TRUE v3
# 6 TRUE FALSE TRUE v1 and v3
# 7 FALSE TRUE TRUE v2 and v3
# 8 TRUE TRUE TRUE All
3
这里有一个方法依靠TRUE/FALSE
可以表示为0和1的事实。您可以将布尔值乘以列索引,然后将所有值粘贴在一起。这会告诉你哪一列的每行的值为1。这里有一个例子:
set.seed(1)
dat <- data.frame(v1 = sample(c(T,F), 10, TRUE),
v2 = sample(c(T,F), 10, TRUE),
v3 = sample(c(T,F), 10, TRUE),
v4 = sample(c(T,F), 10, TRUE)
)
#End fake data
#Multiple T/F times the column index
dat <- dat * rep(seq_len(ncol(dat)), each = nrow(dat))
#Paste together in a new column
dat$v5 <- apply(dat, 1, function(x) paste(x, collapse = ""))
> dat
v1 v2 v3 v4 v5
1 0 0 3 4 0034
2 0 2 0 4 0204
...
结合下面的有益的意见和附加问题
我会用expand.grid()
创建一个查找表,然后写,但是你认为合适的文本标签来表示它们。下面是两列的一个示例:
set.seed(1)
dat <- data.frame(v1 = sample(c(T,F), 10, TRUE),
v2 = sample(c(T,F), 10, TRUE)
)
#Thanks @Joshua
dat$comp <- as.character(apply(1 * dat, 1, paste, collapse=""))
#Look up table
lookup <- data.frame(comp = apply(expand.grid(0:1, 0:1), 1, paste, collapse = ""),
text = c("none", "v1 only", "v2 only", "all"),
stringsAsFactors = FALSE
)
#Use merge to join the look up table to your data. Note the consistent naming of the comp column
> merge(dat, lookup)
comp v1 v2 text
1 00 FALSE FALSE none
2 00 FALSE FALSE none
3 01 FALSE TRUE v2 only
....
1
set.seed(123)
> dat <- data.frame(v1 = sample(c(T,F), 10, TRUE),
+ v2 = sample(c(T,F), 10, TRUE),
+ v3 = sample(c(T,F), 10, TRUE),
+ v4 = sample(c(T,F), 10, TRUE)
+ )
> dat
第一策略使用的模式来索引的各种组合成字符的以1:1的缺省索引“其他”的载体:
> dat$bcateg <- c("Other", "v2 only", "v1 and v3", "All")[1+
+ with(dat, 1*(v2 & !v1 &!v3 &!v4))
+ +with(dat, 2*(v1&v3))+
+ with(dat, v1&v2&v3&v4)]
> dat
v1 v2 v3 v4 bcateg
1 TRUE FALSE FALSE FALSE Other
2 FALSE TRUE FALSE FALSE v2 only
3 TRUE FALSE FALSE FALSE Other
4 FALSE FALSE FALSE FALSE Other
5 FALSE TRUE FALSE TRUE Other
6 TRUE FALSE FALSE TRUE Other
7 FALSE TRUE FALSE FALSE v2 only
8 FALSE TRUE FALSE TRUE Other
9 FALSE TRUE TRUE TRUE Other
10 TRUE FALSE TRUE TRUE v1 and v3
第二种策略使用“,”的分隔符将TRUE的列名联合起来:
> dat$bcateg2 <-paste(c("","v1")[dat[["v1"]]+1 ], c("","v2")[dat[["v2"]]+1 ], c("","v3")[dat[["v3"]]+1 ], c("","v4")[dat[["v4"]]+1 ], sep = ",")
> dat
v1 v2 v3 v4 bcateg bcateg2
1 TRUE FALSE FALSE FALSE Other v1,,,
2 FALSE TRUE FALSE FALSE v2 only ,v2,,
3 TRUE FALSE FALSE FALSE Other v1,,,
4 FALSE FALSE FALSE FALSE Other ,,,
5 FALSE TRUE FALSE TRUE Other ,v2,,v4
6 TRUE FALSE FALSE TRUE Other v1,,,v4
7 FALSE TRUE FALSE FALSE v2 only ,v2,,
8 FALSE TRUE FALSE TRUE Other ,v2,,v4
9 FALSE TRUE TRUE TRUE Other ,v2,v3,v4
10 TRUE FALSE TRUE TRUE v1 and v3 v1,,v3,v4
2
让我把我的帽子环以及
plyr::adply(dat, 1, function(x) paste(names(Filter(isTRUE, x)), collapse = " and "))
v1 v2 v3 v4 V1
1 TRUE TRUE FALSE TRUE v1 and v2 and v4
2 TRUE TRUE TRUE FALSE v1 and v2 and v3
3 FALSE FALSE FALSE TRUE v4
4 FALSE TRUE TRUE TRUE v2 and v3 and v4
5 TRUE FALSE TRUE FALSE v1 and v3
6 FALSE TRUE TRUE FALSE v2 and v3
7 FALSE FALSE TRUE FALSE v3
8 FALSE FALSE TRUE TRUE v3 and v4
9 FALSE TRUE FALSE FALSE v2
10 TRUE FALSE TRUE TRUE v1 and v3 and v4
相关问题
- 1. 比较向量和打印布尔
- 2. 布尔比较
- 3. CriteriaBuilder布尔比较
- 4. Python布尔比较
- 5. EXC_BAD_INSTRUCTION评估布尔比较
- 6. 比较HttpContext的布尔我
- 7. 简化Java布尔比较
- 8. 布尔数组值比较
- 9. 比较可空(布尔值)
- 10. OCaml的布尔比较
- 11. 比较两个布尔值
- 12. TSQL布尔比较语法
- 13. Python中的布尔比较
- 14. 比较ArrayLists和布尔值
- 15. Javascript比较布尔值
- 16. C++比较向量
- 17. 使用=和==比较布尔值与布尔变量有什么区别?
- 18. 如何使用SIMD比较两个向量并获得单个布尔结果?
- 19. 如何简化C++布尔比较
- 20. 蟒蛇基本语法布尔比较
- 21. 字符串比较上一个布尔
- 22. 是布尔还是零比较更快?
- 23. 不可预知的布尔比较C++
- 24. 这是布尔比较正确的吗?
- 25. 使用“isEqual”比较布尔类型
- 26. DotConnect低效布尔比较SQL代
- 27. 字符串上的布尔比较
- 28. jsRender如何做布尔比较
- 29. 布尔数组比较的Java
- 30. ios比较来自json的布尔值
+1做得很好。使用0/1表示的另一种选择是将每个乘以10的幂并加上;这可以通过矩阵乘法完成,就像这个`as.matrix(dat)%*%10^rev(seq_len(ncol(dat)) - 1)`一样。 (或者如果你更喜欢用二进制来思考,则使用2的幂。) – Aaron 2011-12-14 02:55:34
+1,但是我没有看到“列索引”的需要,因为它是由字符串中的“1”的位置定义的。替代方法是`apply(1 * dat,1,paste,collapse =“”)或`do.call(paste,c(1 * dat,sep =“”))``。 – 2011-12-14 03:15:03
谢谢。所以根据你的回答,我想到了以下几点:`v1 < - ifelse(v1 == TRUE,1000,0)``v2 < - ifelse(v1 == TRUE,100,0)``v3 < - ifelse(v1 == TRUE,10,0)``v4 < - ifelse(v1 == TRUE,1,0)``dat $ v5 < - sum(v1,v2,v3,v4)`然后我应该创建一个要查找标签的值列表(例如1111 ==“All”)还是有更好的方法? – 2011-12-14 03:59:51