这是生成一些样本数据的代码:
set.seed(1000)
dat <- data.frame(A = runif(5, -5, 5),
B = runif(5, -5, 5),
C = runif(5, -5, 5))
数据:
A B C
1 -1.721213 -4.3226204 -1.500625
2 2.588465 2.3871486 2.554616
3 -3.860636 0.8353505 -1.829158
4 1.907551 -2.8422860 3.658128
5 0.164024 -2.4387760 2.641607
我想比较每一列并返回
TRUE
或FALSE
,这取决于在逐行浏览时是否存在负值或正值。例如,在A和B列的第4行中,我们将得到TRUE
。因为一个是积极的,另一个是消极的。如果被交换(该行的A中为负值,但B中为正值),则它还将返回TRUE
。但是,如果要比较的两个值中的任何一个介于1到-1之间,则不会进行比较,它只会返回
NA
。此示例的最终输出如下所示: A B C AB BC AC
1 -1.721213 -4.3226204 -1.500625 FALSE FALSE FALSE
2 2.588465 2.3871486 2.554616 FALSE FALSE FALSE
3 -3.860636 0.8353505 -1.829158 NA NA FALSE
4 1.907551 -2.8422860 3.658128 TRUE TRUE FALSE
5 0.164024 -2.4387760 2.641607 NA TRUE NA
我试图使用这种逻辑比较行:
if((dat$A > 1 & datB < -1) | (dat$A < -1 & dat$B > -1) == TRUE)
...但我认为必须有一种更有效的方法。
看到一些答案后进行编辑:
当我测试它们时,这里有很多很棒的答案都起作用了。我最喜欢mpalanco的答案,因为它的可读性和简洁性。但是,我选择了DMC的答案,因为它可以推广到其他情况,并且可能对其他人寻找该问题或类似问题的答案很有用。
最佳答案
如果您拥有的列多于{A, B, C}
且您想查看所有成对的列,则得出以下结果:
library(tidyr)
library(dplyr)
# get original names
orig_names <- names(dat)
# add a row indicator
dat <- dat %>% mutate(k = row_number())
dat2 <- dat %>%
# reshape to long
gather(letter, value, A:C) %>%
# change value to {-1, 1}
mutate(
value = ifelse(value <= -1, -1, ifelse(value >= 1, 1, NA)),
letter = as.character(letter)
)
# create a placeholder data frame for result
d_new <- expand.grid(
V1 = orig_names,
V2 = orig_names,
k = 1:nrow(dat),
stringsAsFactors = FALSE
) %>%
filter(V1 < V2)
# compute result
result <- d_new %>%
left_join(dat2, by = c("V1" = "letter", "k" = "k")) %>%
left_join(dat2, by = c("V2" = "letter", "k" = "k")) %>%
mutate(
result = (value.x != value.y),
combo = paste0(V1, V2)
) %>%
select(-starts_with("value"), -V1, -V2) %>%
spread(combo, result)
# join with original data
dat %>% left_join(result)
## A B C k AB AC BC
## 1 -1.721213 -4.3226204 -1.500625 1 FALSE FALSE FALSE
## 2 2.588465 2.3871486 2.554616 2 FALSE FALSE FALSE
## 3 -3.860636 0.8353505 -1.829158 3 NA FALSE NA
## 4 1.907551 -2.8422860 3.658128 4 TRUE FALSE TRUE
## 5 0.164024 -2.4387760 2.641607 5 NA NA TRUE