2016-06-29 2 views
1

моих данных как этогорасщепленных строк в разные столбцы на основе точки с запятой

dff<- structure(c(7L, 6L, 5L, 4L, 3L, 2L, 1L, 1L, 1L), .Label = c("", 
"P42356;Q8N8J0;A4QPH2", "P67809;Q9Y2T7", "Q08554", "Q13835", 
"Q5T749", "Q9NZT1"), class = "factor") 

я пытаюсь разделить мои строки и сделать их в разных колонках

, например, вывод должен выглядеть следующим образом

A  B  C   
Q9NZT1 
Q5T749 
Q13835 
Q08554 
P67809 Q9Y2T7 
P42356 Q8N8J0 A4QPH2 

Я попытался использовать strsplit, но это не сработало.

unlist(strsplit(dff, ";", fixed = TRUE)) 

Благодаря @thepule я пытаюсь сделать правило. каждая строка сначала остается в том же столбце. если он отделен а; затем он переходит к следующему колонку, но остается в той же строке

+1

@thepule хороший вопрос. каждая строка встречалась сначала в том же столбце. если он отделен а; то он переходит к следующему столбцу, ясно? – nik

+0

@ user5249203 Я пробовал эти ответы, не работал для меня – nik

ответ

1

Ах, похоже, только я один, используя основной признак Р.

x <- strsplit(as.character(dff), ";") 
l <- lengths(x) ## R 3.3.0 onward 
m <- max(l) 
x <- t(sapply(x[as.logical(l)], function(a) c(a, rep("",m-length(a))))) 

x 
#  [,1]  [,2]  [,3]  
# [1,] "Q9NZT1" ""  ""  
# [2,] "Q5T749" ""  ""  
# [3,] "Q13835" ""  ""  
# [4,] "Q08554" ""  ""  
# [5,] "P67809" "Q9Y2T7" ""  
# [6,] "P42356" "Q8N8J0" "A4QPH2" 

Если вы хотите кадр данных, просто принуждать эту матрицу в кадр данных по as.data.frame(x):

#  V1  V2  V3 
# 1 Q9NZT1    
# 2 Q5T749    
# 3 Q13835    
# 4 Q08554    
# 5 P67809 Q9Y2T7  
# 6 P42356 Q8N8J0 A4QPH2 

Последующая деятельность

Что касается вашего последующего запроса, мы можем сделать:

x <- strsplit(as.character(dff), ";") 
ind <- as.logical(l <- lengths(x)) ## R 3.3.0 onward 
m <- max(l <- l[ind]) 
x <- t(sapply(x[ind], function(a) c(paste(a,1:length(a),sep="_"), rep("",m-length(a))))) 
ind <- l==1L; x[ind,1] <- gsub("_1","",x[ind,1]) 

#  [,1]  [,2]  [,3]  
# [1,] "Q9NZT1" ""   ""   
# [2,] "Q5T749" ""   ""   
# [3,] "Q13835" ""   ""   
# [4,] "Q08554" ""   ""   
# [5,] "P67809_1" "Q9Y2T7_2" ""   
# [6,] "P42356_1" "Q8N8J0_2" "A4QPH2_3" 

Снова используйте as.data.frame если вы хотите кадр данных. Я, наконец, использую один gsub, потому что я не хочу использовать if...else или ifelse внутри sapply, что увеличит накладные расходы R.

+0

Я хочу знать, знаете ли вы, как я могу положить те, которые разделены; в отдельной ячейке? – nik

3

Я люблю splitstackshape пакета для этих угловатого типа данных:

dff<- c("", "P42356;Q8N8J0;A4QPH2", "P67809;Q9Y2T7", "Q08554", "Q13835", 
"Q5T749", "Q9NZT1") 

library(splitstackshape) 

cSplit(data.frame(dff), 'dff', ";") 

#  dff_1 dff_2 dff_3 
# 1:  NA  NA  NA 
# 2: P42356 Q8N8J0 A4QPH2 
# 3: P67809 Q9Y2T7  NA 
# 4: Q08554  NA  NA 
# 5: Q13835  NA  NA 
# 6: Q5T749  NA  NA 
# 7: Q9NZT1  NA  NA 
+0

закрыть, но те, которые перемещены в новый столбец, должны оставаться в одной строке – nik

+0

Я не понимаю вашу логику, но, вероятно, можно было бы сделать с суммой строк на не ' NA' с сортировкой. –

+0

В моем вопросе я добавил логику. Я думаю, что ваше решение хорошо, но только перевернуто: - Посмотрите на строку на 7 строке, на моем выходе - 1 строку. посмотрите на 6-й, что на моем выходе второй и т. д. – nik

1

У меня есть еще один чрезвычайно супер жестокое решение:

library(dplyr) 
library(stringr) 

list <- lapply(str_split(dff, ";"), function(x) { 
     if(x[1] != "") data.frame(lapply(x, data.frame), stringsAsFactors = F) 
}) 

list <- list[!sapply(list, is.null)] 
final <- bind_rows(list) 

final 
Source: local data frame [6 x 3] 

    X..i.. X..i...1 X..i...2 
    (chr) (chr) (fctr) 
1 Q9NZT1  NA  NA 
2 Q5T749  NA  NA 
3 Q13835  NA  NA 
4 Q08554  NA  NA 
5 P67809 Q9Y2T7  NA 
6 P42356 Q8N8J0 A4QPH2 
+1

@hepule приятно, сложно визуализировать его для меня :-) но приятное решение :-) – nik

+1

@nik да, это было больше для удовольствия: P – thepule

+1

Мне понравилось ваше решение для его красоты :-D – nik

2

Вы можете построить фрейм данных с вашего вектора, а затем отделить его:

tidyr::separate(data.frame(text = dff), text, into = c("A", "B", "C"), sep = ";", fill = "right", extra = "drop") 
     A  B  C 
1 Q9NZT1 <NA> <NA> 
2 Q5T749 <NA> <NA> 
3 Q13835 <NA> <NA> 
4 Q08554 <NA> <NA> 
5 P67809 Q9Y2T7 <NA> 
6 P42356 Q8N8J0 A4QPH2 

данные:

c("Q9NZT1", "Q5T749", "Q13835", "Q08554", "P67809;Q9Y2T7", "P42356;Q8N8J0;A4QPH2" 
) 
+0

приятно, но это в случае, если я знаю, что у меня есть только три строки заранее, чтобы я мог установить их в A, B и C, но если я не знаю и если их много, тогда это будет создать так много НС в конце тоже, нет? – nik

+0

Да. Если вы не очень хорошо знаете свой текст, лучше написать собственный парсер, как это сделали другие. Но если вы знаете максимальные столбцы, которые у вас есть или вы хотите сохранить, это будет хороший метод. – Psidom

+0

'cSplit (as.data.frame (dff)," dff ", sep ="; ", drop = TRUE)' работает для меня –

1

вы шли в правильном направлении (если это не фактор s), strsplit ожидает символьный вектор, и когда создается список, все, что вам нужно, это rbind.

***With your input data*** 
# Not sure why you want them as factors 

Это все еще работает ...

my_list <- strsplit(as.character(dff), ';') 

require(plyr) 
res<- ldply(my_list ,rbind) 

выход

1  2  3 
1 Q9NZT1 <NA> <NA> 
2 Q5T749 <NA> <NA> 
3 Q13835 <NA> <NA> 
4 Q08554 <NA> <NA> 
5 P67809 Q9Y2T7 <NA> 
6 P42356 Q8N8J0 A4QPH2 
+0

вы изменили исходный dff на ярлык, чтобы передать его на strsplit? веселая ! спасибо, что ваше решение перевернуто! посмотри на мой вопрос – nik

+0

Я не понял. Неправильно ли введены данные? Результат - это то, что вы хотели? – user5249203

+0

Мне тоже понравился ваш ответ, – nik

1
library(splitstackshape) 
res <- cSplit(data.frame(dff), "dff", sep=";", drop=TRUE) 

То есть все, что вам нужно. Но если испуг Акрополя вы:

res[] <- lapply(res, as.character) 
res[is.na(res)] <- '' 
+0

Что значит «это не работает» означает точно –

+0

О, это работает, я сделал опечатку, один вопрос вы знаете, как остановить столбец, называя его? мой смысл просто не генерировать имена столбцов при использовании вашей функции? – nik

+0

Нет, но вы можете удалить их после «имен (res) <- NULL» –

2

вы также можете использовать str_split который vectorised над строкой и рисунком, таким образом, вам не нужно преобразовывать его характер

library(plyr) 
library(stringr) 
x <- str_split(dff, ";") 
res<- ldply(x ,bind) 
#  1  2  3 
#1 Q9NZT1 <NA> <NA> 
#2 Q5T749 <NA> <NA> 
#3 Q13835 <NA> <NA> 
#4 Q08554 <NA> <NA> 
#5 P67809 Q9Y2T7 <NA> 
#6 P42356 Q8N8J0 A4QPH2 
#7   <NA> <NA> 
#8   <NA> <NA> 
#9   <NA> <NA> 
+0

спасибо, но все же он дает несколько НС – nik

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