繁体   English   中英

比较R中的多个布尔列

[英]Compare multiple boolean columns in r

小填字游戏。 和往常一样,我认为我缺少了一些东西。 我有一个这样的数据框:

id creator att1 att2 att3 att... att500
a1 person1 TRUE TRUE FALSE ...
a2 person2 TRUE TRUE TRUE ...
a3 person1 TRUE FALSE FALSE ...
a4 person1 TRUE TRUE FALSE ...
a5 person2 TRUE TRUE FALSE ...

等等。 我想计算不同创建者的相同属性组合(大约500个布尔值)的出现次数,并针对每一行执行此操作,将计数添加到相应的行中。 因此,在上面的示例中,我希望第一行(a1)的count = 1,因为在a5中,其他人执行了非常相同的属性组合。 请注意,a4不计算在内,因为它是相同的组合,但是是同一个人的。 想一想自己混合的鸡尾酒,以及不同人彼此独立地混合鸡尾酒的频率。 行a2的计数应为0,由于a5,a3(没有相同的属性组合)和a4的计数应分别为1。 a5的计数也为1。 但是,如果其他人多次混合同一鸡尾酒,则应计算在内。 我不想简单地删除重复项。

因此,我的计划是遍历行,排除行的同一创建者的所有鸡尾酒,采用属性组合,并将其与临时数据集中的所有行进行比较:

for (row in 1:nrow(data)){ 
# for each row in data
   creator <- row$creator 
# get creator
   attr_tupel <- row[1, 3:500] 
#return the attribute combination of the row
   data[row]$count <- nrow(data[data$creator != creator & data[3:500] == attr_tupel]) 
# into the column $count of the current row write the number of observations that are not from the same creator and match the exact tupel of my ~500 Attributes (equal cocktails by different persons)
}

不幸的是,我无法将参考行的tupel与其他行的tupel进行比较,因为“ ==”仅针对大小相等的数据帧定义

现在我被卡住了。 我肯定可以分别写每一列-但是要花一些时间。 我是否需要将该数据帧转换为列表或向量,或者//在此处插入sthg // (向量和列表不起作用。)是否可以将值的一行与其他许多行进行比较以求相等? 我不认为有重复的行是解决方案,除了通常R会在没有任何可比较的条件时简单地遍历条目。 为什么不在这里?

我读了一些有关相互比较几列的主题,但是没有成功地将解决方案转移到我的问题上。 例如: 想为布尔值查找一个值,我有多个TRUE值 ,同一个想要转换为ac(),我也可以这样做并比较它们,但是有点困难,不是吗?

最后(从最后一个链接开始)我现在甚至在考虑将布尔值转换为数字(添加索引,以便

id creator att1 ... index
a1 person1 1 2 0 ... 3 
a2 person2 1 2 3 ... 6

并比较该指数。 应该管用。 但是那种感觉是一个丑陋的解决方法。 同样,当考虑使用布尔值以外的数据(例如多个字符串)时,从长远来看,我仍然希望能够将列的Tupel相互比较,而与它们的内容无关。

我想念什么? :)

谢谢你的帮助!

如评论中所要求的,这里是创建类似数据框的简短脚本。 请记住,尽管有更多的列可以比较。

id <- 1:50
names <- paste("creator", rep(1:10, each = 5))
bools1 <- rnorm(n=50, mean = 5, sd = 3)
bools1 <- ifelse(bools1>5, TRUE, FALSE)
bools2 <- rnorm(n=50, mean = 5, sd = 3)
bools2 <- ifelse(bools2>5, TRUE, FALSE)
bools3 <- rnorm(n=50, mean = 5, sd = 3)
bools3 <- ifelse(bools3>5, TRUE, FALSE)
bools4 <- rnorm(n=50, mean = 5, sd = 3)
bools4 <- ifelse(bools4>5, TRUE, FALSE)
bools5 <- rnorm(n=50, mean = 5, sd = 3)
bools5 <- ifelse(bools5>5, TRUE, FALSE)

data <- data.frame(id, names, bools1, bools2, bools3, bools4, bools5)

编辑 :对不起-我的第一个解决方案误解了问题。 试试这个

您可以使用数据表来运行它:

#Your set up data (with seed)
set.seed(123)
id <- 1:50
names <- paste("creator", rep(1:10, each = 5))
bools1 <- rnorm(n=50, mean = 5, sd = 3)
bools1 <- ifelse(bools1>5, TRUE, FALSE)
bools2 <- rnorm(n=50, mean = 5, sd = 3)
bools2 <- ifelse(bools2>5, TRUE, FALSE)
bools3 <- rnorm(n=50, mean = 5, sd = 3)
bools3 <- ifelse(bools3>5, TRUE, FALSE)
bools4 <- rnorm(n=50, mean = 5, sd = 3)
bools4 <- ifelse(bools4>5, TRUE, FALSE)
bools5 <- rnorm(n=50, mean = 5, sd = 3)
bools5 <- ifelse(bools5>5, TRUE, FALSE)

data <- data.frame(id, names, bools1, bools2, bools3, bools4, bools5)

# Code to run

library(data.table)

setDT(data)
dt_m <- melt(data, id.vars = c("id","names"), variable.factor = TRUE)
dt_m <- dt_m[,.(drink = paste0(value, collapse = "_")), by = .(id, names)]
dt_m[, times_made := .N, by = drink][, times_made_others := times_made - .N, by = .(drink, names)]
dt_out <- merge(data, dt_m[, .(id, drink, times_made_others)], by = "id")

本质上,您正在做的是通过将各列折叠在一起,计算其他人制作饮料的次数,然后将其合并回原始数据集来创建“饮料”。

dt_out
    id      names bools1 bools2 bools3 bools4 bools5                        drink times_made_others
 1:  1  creator 1  FALSE   TRUE  FALSE   TRUE   TRUE   FALSE_TRUE_FALSE_TRUE_TRUE                 3
 2:  2  creator 1  FALSE  FALSE   TRUE   TRUE   TRUE   FALSE_FALSE_TRUE_TRUE_TRUE                 1
 3:  3  creator 1   TRUE  FALSE  FALSE   TRUE  FALSE  TRUE_FALSE_FALSE_TRUE_FALSE                 2
 4:  4  creator 1   TRUE   TRUE  FALSE  FALSE   TRUE   TRUE_TRUE_FALSE_FALSE_TRUE                 0
 5:  5  creator 1   TRUE  FALSE  FALSE  FALSE  FALSE TRUE_FALSE_FALSE_FALSE_FALSE                 3
 6:  6  creator 2   TRUE   TRUE  FALSE  FALSE  FALSE  TRUE_TRUE_FALSE_FALSE_FALSE                 2
 7:  7  creator 2   TRUE  FALSE  FALSE   TRUE  FALSE  TRUE_FALSE_FALSE_TRUE_FALSE                 2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM