2015-12-31 6 views
2

Пусть этот код:Извлечь список частей в векторе с помощью plyr :: mutate?

foo <- data.frame(cols_val=c("NA", "1:2:3", "4:5:6")) 
library(plyr) 
foo <- mutate(
    foo, 
    cols_list = str_split(cols_val, ":"), 
    one = cols_list[1], 
    two = cols_list[2]) 

Я хотел foo$one быть c(NA, "1", "4") и foo$two быть c(NA, "2", "5"). То есть, чтобы разделить значения cols_val на отдельные столбцы кадра данных.

Однако cols_list представляет собой список, и one == cols_list[1] является первым элементом этого списка (== cols_list[[1]]), в то время как two == cols_list[1]. Итак, я не знаю, как правильно это сделать.

Помощь?

> foo 
    cols_val cols_list one  two 
1  NA  NA NA 1, 2, 3 
2 1:2:3 1, 2, 3 NA 1, 2, 3 
3 4:5:6 4, 5, 6 NA 1, 2, 3 

> str(foo$cols_list) 
List of 3 
$ : chr "NA" 
$ : chr [1:3] "1" "2" "3" 
$ : chr [1:3] "4" "5" "6" 
+1

Попробуйте 'library (splitstackshape); cSplit (foo, 'cols_val', ":") ' – akrun

ответ

4

Вместо plyr, вы можете использовать tidyr::separate(). Он делает именно то, что вы хотите сделать. Мы можем сохранить существующий столбец (с remove = FALSE), а также преобразовать все новые столбцы в соответствующий тип (с convert = TRUE). Я использую только fill = "left", чтобы избежать предупреждения, когда он не используется. Я не совсем уверен, почему возникает предупреждение.

tidyr::separate(foo, cols_val, c("one", "two", "three"), ":", 
    remove = FALSE, convert = TRUE, fill = "left") 
# cols_val one two three 
# 1  NA NA NA NA 
# 2 1:2:3 1 2  3 
# 3 4:5:6 4 5  6 
+0

Спасибо! Я думаю, предупреждение происходит потому, что первая строка не может быть разделена на три столбца, используя: – dfrankow

+0

Да. Файл справки говорит, что это как-то связано с 'sep', но я попробовал' sep = rep («:», 2) ', но это тоже не избавилось. Ну что ж. –

2

Мы можем использовать cSplit

library(splitstackshape) 
cSplit(foo, 'cols_val', ":") 
#  cols_val_1 cols_val_2 cols_val_3 
#1:   NA   NA   NA 
#2:   1   2   3 
#3:   4   5   6 

По умолчанию исходный столбец будет отброшен, как drop=TRUE. Если нам также нужно сохранить исходный столбец, используйте drop=FALSE. Он также преобразует «класс» по умолчанию

cSplit(foo, 'cols_val', ":", drop=FALSE) 
# cols_val cols_val_1 cols_val_2 cols_val_3 
#1:  NA   NA   NA   NA 
#2: 1:2:3   1   2   3 
#3: 4:5:6   4   5   6