2014-08-28 1 views
1

У меня есть очень большой DF, структура выглядит следующим образом:поиска дубликатов в столбце значениях каждой строки/сравнение столбец значений по строкам

route_1 route_2 route_3 route_4 route_grey_1 route_grey_2 
A  B  NA  NA  NA   NA 
A  B  C  NA  A   NA 
A  B  C  D  A   D 
A  B  C  NA  C   NA 
B  C  E  F  B   C 

Однако A,B,C,D будет отличаться между рядами , Для каждой строки я пытаюсь найти два значения route_1 для route_4, которые не упоминаются в route_grey_1 и route_grey_2. Это всегда будет ровно 2 значения. (если в route_n есть только два значения, то не будет значения route_grey_n, если в route_n есть три значения, чем одно значение в route_grey_n и т. д.)

Таким образом, приведенный выше ввод должен привести к этому выводу (добавление две новые колонки:

route_1 route_2 route_3 route_4 route_grey_1 route_grey_2 result1 result2 
A  B  NA  NA  NA   NA   A  B 
A  B  C  NA  A   NA   B  C 
A  B  C  D  A   D    B  C 
A  B  C  NA  C   NA   A  B 
B  C  E  F  B   C    E  F 

до сих пор единственным решением, которое пришло мне на ум, чтобы написать функцию, пробегаем по всем строкам и сравнивая один за другим route_n с route_grey_n Во-первых, я думаю, что там может быть. гораздо лучшее решение, и я ожидаю, что цикл будет очень медленным. Во-вторых, я не мог заставить свою работу цикла, поэтому, если вы считаете, что это может быть единственным решением, надеюсь, кто-то может мне помочь.

/е: В то время как ответ Дэвид работает небольшой DF, это занимает 30мин на мои данные и не:

Error: cannot allocate vector of size 380 Kb 
Error during wrapup: cannot allocate vector of size 438 Kb 

Я подозреваю, что должно быть решение, используя dplyr или data.table пакетов.

/e2: После игры с dplyr мне удалось найти решение. Кажется, что он работает и занимает около 30 секунд на моем DF. Однако он очень хаки и может быть не очень хорошим. Поэтому любые улучшения высоко ценятся. Вот мой код:

df <- df %>% group_by(index) %>% 
mutate(c_route1 = !route_1 %in% c(route_grey_1,route_grey_2), 
c_route2 = !route_2 %in% c(route_grey_1,route_grey_2), 
c_route3 = !route_3 %in% c(route_grey_1,route_grey_2), 
c_route4 = !route_4 %in% c(route_grey_1,route_grey_2)) 

Это создает столбцы с логические выражения в ЦФ, а затем он становится уродливым (возможно эта часть может быть сделано гораздо лучше, хотелось бы увидеть некоторые альтернативы):

df$result1[df$c_route1] <- df$route_1[df$c_route1] 
df$result1[!df$c_route1 & df$c_route2 ] <- df$route_2[ !df$c_route1 & df$c_route2 ] 
df$result1[!df$c_route1 & !df$c_route2 ] <- df$route_3[ !df$c_route1 & !df$c_route2 ] 
df$result2[df$c_route1 ] <- df$route_2[ df$c_route1 ] 
df$result2[!df$c_route1 & df$c_route2 ] <- df$route_3[ !df$c_route1 & df$c_route2 ] 
df$result2[!df$c_route1 & !df$c_route2 ] <- df$route_4[ !df$c_route1 & !df$c_route2 ] 

ответ

1

As сколько я пытаюсь избежать apply, это единственное решение, которое я мог думать о

DF[c("result1", "result2")] <- t(apply(DF, 1, function(x) x[1:4][t(!(x[1:4] %in% x[5:6]))])) 

# route_1 route_2 route_3 route_4 route_grey_1 route_grey_2 result1 result2 
# 1  A  B <NA> <NA>   <NA>   <NA>  A  B 
# 2  A  B  C <NA>   A   <NA>  B  C 
# 3  A  B  C  D   A   D  B  C 
# 4  A  B  C <NA>   C   <NA>  A  B 
# 5  B  C  E  F   B   C  E  F 
+0

это то, что я хочу, thanks.Can вы объяснить код? Я этого не понимаю. Также это, как и ожидалось, с применением метода loop/apply очень медленно. – cover51

+0

Код довольно прост. Он просматривает каждую строку и проверяет, какие записи в 'DF [i, 1: 4]' не находятся в 'DF [i, 5: 6]', а затем печатает эти значения. –

Смежные вопросы