Сравните несколько логических столбцов в r - PullRequest
0 голосов
/ 20 ноября 2018

маленький кроссворд.Как всегда, я думаю, что что-то упустил.У меня есть такой фрейм данных:

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 булатских значений) разными создателями и сделать это для каждой строки, добавив счет к соответствующей строке.Следовательно, в приведенном выше примере я хочу, чтобы count = 1 для первой строки (a1), потому что в a5 другой человек сделал ту же самую комбинацию атрибутов.Обратите внимание, что a4 не считается, потому что это та же комбинация, но от одного и того же человека.Подумайте о самостоятельно смешанных коктейлях и частоте их смешивания разными людьми независимо друг от друга.строка a2 должна иметь счетчик 0, поэтому a3 (без одинаковой комбинации атрибутов) и a4 соответственно считают = 1 из-за a5.У 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)
}

К сожалению, я не могу сравнить толщину базовой строки с другими строками, поскольку '==' определено только для фреймов данных одинакового размера

А теперьЯ застрял.Я мог бы точно написать каждый столбец отдельно - но это заняло бы целую вечность.Нужно ли приводить этот фрейм данных в список или вектор или // вставить сюда sthg // (вектор и список не работает.) Можно ли вообще сравнивать одну строку значений со многими другимистроки на равенство?Я не думаю, что иметь дубликат строки было бы решением, к тому же обычно R просто перебирает записи, когда ему больше нечего сравнивать.Почему бы и нет?

Я прочитал несколько статей о сравнении нескольких столбцов друг с другом, но не смог перенести решение моей проблемы.Например: хочет найти одно значение для значения boolish, у меня есть несколько значений TRUE , то же самое , хочет преобразовать в ac () - что я тоже мог бы сделать иСравните их, но довольно сложно, не так ли?

Наконец (из этой последней ссылки) я теперь даже думал о том, чтобы преобразовать логические значения в число (добавив индексы, чтобы мы получили

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

и сравнил этот индексДолжно работать. Но такое ощущение, что это уродливый обходной путь. Также, когда я думаю о наличии данных, отличных от логических, например, нескольких строк, я все же в конечном итоге хотел бы иметь возможность сравнивать набор столбцов друг с другом независимоих содержания.

Чего мне не хватает?:)

Спасибо за вашу помощь!

, как и просили в комментарии, вот короткий скрипт для создания аналогичного фрейма данных.Имейте в виду, что столбцов для сравнения гораздо больше.

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)

1 Ответ

0 голосов
/ 20 ноября 2018

РЕДАКТИРОВАТЬ : Извините, мое первое решение неправильно прочитало вопрос.Попробуйте вместо этого

Вы можете запустить это, используя таблицу данных:

#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
...