2016-08-23 5 views
2

Примера, который работает:dplyr :: мутирует: - новый столбец = разница между двумя запятыми списка столбцами

df <- data.frame(c0=c(1, 2), c1=c("A,B,C", "D,E,F"), c2=c("B,C", "D,E")) 
df 
# c0 c1 c2 
# 1 1 A,B,C B,C 
# 2 2 D,E,F D,E 

# Add a column d with difference between c1 and c2 
df %>% mutate(d=setdiff(unlist(strsplit(as.character(c1), ",")), unlist(strsplit(as.character(c2), ",")))) 

# c0 c1 c2 d 
# 1 1 A,B,C B,C A 
# 2 2 D,E,F D,E F 

я получаю то, что я ожидал выше: D присваивается разница между этими двумя списками символов (они уже отсортированы). не

Однако, если я представлю более чем один другой характер она больше не работает:

df <- data.frame(c0=c(1, 2), c1=c("A,B,C", "D,E,F,G"), c2=c("B,C", "D,E")) 
df 
# c0  c1 c2 
# 1 1 A,B,C B,C 
# 2 2 D,E,F,G D,E 

# Add a column d with difference between c1 and c2 
df %>% mutate(d=setdiff(unlist(strsplit(as.character(c1), ",")), unlist(strsplit(as.character(c2), ",")))) 
Error: wrong result size (3), expected 2 or 1 

То, что я хотел, чтобы получить там:

c0 c1 c2 d 
1 1 A,B,C B,C A 
2 2 D,E,F,G D,E F,G 

Я попытался добавить в paste() вокруг setdiff но это не помогло. В конце концов, я на самом деле хочу, чтобы иметь возможность, вероятно, использовать tidyr::separate расколоть из столбца D в новые строки, как:

c0 c1 c2 d 
1 1 A,B,C B,C A 
2 2 D,E,F,G D,E F 
3 2 D,E,F,G D,E G 

Что я делаю не так с выше setdiff?

Благодаря

Tim

ответ

1

Вы получите ошибку, потому что в строке 2 у вас есть более чем один элемент, который не может поместиться в ячейку, один из способов заключается в использовании rowwise и обернуть результат в виде списка, так что может соответствовать и после этого использования unnest из tidyr расширить столбец типа списка:

library(dplyr) 
library(tidyr) 
df %>% 
     rowwise() %>% 
     mutate(d=list(setdiff(unlist(strsplit(as.character(c1), ",")), 
          unlist(strsplit(as.character(c2), ","))))) %>% 
     unnest() 

# Source: local data frame [3 x 4] 

#  c0  c1  c2  d 
# <dbl> <fctr> <fctr> <chr> 
# 1  1 A,B,C B,C  A 
# 2  2 D,E,F,G D,E  F 
# 3  2 D,E,F,G D,E  G 
+0

Brilliant - спасибо! – Tim

+0

Я до сих пор не встречал ролей и невнимательности. Чтобы проверить, что я понимаю: rowwise делает последующее обобщение и мутацию операций в пределах каждой строки (когда я попытался вставить, как указано выше, без объединения, объединил значения из всех строк). unsest делает то, что я предлагаю 'tidyr :: separate' for - дублирует строки для каждого элемента списка в d. Я нашел это сообщение полезным для беспокойства: http://bioinfoblog.it/2015/02/the-most-useful-r-command-unnest-from-tidyr/comment-page-1/. Еще раз спасибо @Psidom – Tim

+0

Паста не сработает, потому что она векторизована и, таким образом, обработает столбец в виде вектора, если нет привязки для ограничения операции по строкам; 'separate' предназначен для разбиения столбца на несколько столбцов, а' unnest' - расширение столбца, в котором каждый элемент представляет собой список, как в этом случае. – Psidom

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