2015-07-01 2 views
6

Я хотел бы создать последний столбец ('wish_result') из 3 предыдущих столбцов ('group', 'animal' и 'full'). Ниже приведен код для воспроизводимого примера.Удалить строки из списка

library(data.table) 
data = data.table(group = c(1,1,1,2,2,2), animal = c('cat', 'dog', 'pig', 'giraffe', 'lion', 'tiger'), desired_result = c('dog, pig', 'cat, pig', 'cat, dog', 'lion, tiger', 'giraffe, tiger', 'giraffe, lion')) 
data[, full := list(list(animal)), by = 'group'] 
data = data[, .(group, animal, full, desired_result)] 

data 
    group animal    full desired_result 
1:  1  cat   cat,dog,pig  dog, pig 
2:  1  dog   cat,dog,pig  cat, pig 
3:  1  pig   cat,dog,pig  cat, dog 
4:  2 giraffe giraffe,lion,tiger lion, tiger 
5:  2 lion giraffe,lion,tiger giraffe, tiger 
6:  2 tiger giraffe,lion,tiger giraffe, lion 

В принципе, я хотел бы изменить «полный», чтобы он не включал соответствующее «животное». Я пробовал различные команды lapply, используя как списки, так и символьные версии этих столбцов, но не смог решить эту проблему.

ответ

3

Вот возможный подход

data[, desired_result := { 
     temp <- unique(unlist(full)) 
     toString(temp[-match(animal, temp)]) 
     }, by = .(group, animal)] 
data 
# group animal    full desired_result 
# 1:  1  cat  cat,dog,pig  dog, pig 
# 2:  1  dog  cat,dog,pig  cat, pig 
# 3:  1  pig  cat,dog,pig  cat, dog 
# 4:  2 giraffe giraffe,lion,tiger lion, tiger 
# 5:  2 lion giraffe,lion,tiger giraffe, tiger 
# 6:  2 tiger giraffe,lion,tiger giraffe, lion 
3

Другой вариант:

data[, desired := .(Map(setdiff, list(animal), as.list(animal))), by = group] 

#or if starting from full 
data[, desired := .(Map(setdiff, full, animal))] 

(рециркуляция магия делает первую версию работы)

+0

Такая же идея в 'dplyr':' library (dplyr); data%>% mutate (желательно = Карта (setdiff, full, animal)) ' –

+0

Это даст список обратно вместо символьного вектора (в соответствии с желаемым выходом OP). –

+1

Я читал OP, так как им все равно, получают ли они список или строку, а преобразование тривиально. – eddi

1

Я нашел способ, как хорошо!

Поворачивая «животное» в список, я могу использовать mapply.

data$animal = strsplit(data$animal, ' ') 
data$check = mapply(function(x, y) {list(x[x != y]) }, data$full, data$animal) 

data 
group animal    full desired_result   check 
1:  1  cat  cat,dog,pig  dog, pig  dog,pig 
2:  1  dog  cat,dog,pig  cat, pig  cat,pig 
3:  1  pig  cat,dog,pig  cat, dog  cat,dog 
4:  2 giraffe giraffe,lion,tiger lion, tiger lion,tiger 
5:  2 lion giraffe,lion,tiger giraffe, tiger giraffe,tiger 
6:  2 tiger giraffe,lion,tiger giraffe, lion giraffe,lion 
+0

. Ваш подход вернет список обратно вместо символьного вектора (в соответствии с вашим желаемым результатом). –

+0

Хорошо, хорошо, что нужно было бы преобразовать и очистить, если необходимо. – DataBandit

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