несколько упорядоченных strsplit, затем рекомбинировать

Дан вектор символьных строк, где каждая строка представляет собой список названий видов, разделенных запятыми (т. Е. Род видов). Каждая строка может содержать переменное количество видов (например, как показано в примере ниже, количество видов в данной строке варьируется от 1 до 3).

trees <-  c("Erythrina poeppigiana", "Erythrina poeppigiana, Juglans regia x Juglans nigra", "Erythrina poeppigiana, Juglans regia x Juglans nigra, Chloroleucon eurycyclum") 

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

genera <- c("Erythrina", "Erythrina, Juglans", "Erythrina, Juglans, Chloroleucon")

Виноградный вид - это гибрид гибридов "Juglans regia x Juglans nigra". Это должно получиться просто как «Juglans», так как все это заключено между двумя запятыми и, следовательно, является всего лишь одним видом. В таких гибридах род всегда один и тот же по обе стороны от «x», поэтому достаточно первого слова в этой части строки, как и в более стандартных случаях. Однако решения, которые пытаются вытащить «каждое слово», не будут работать из-за этих гибридов.

Моя попытка заключалась в том, чтобы сначала разделить strsplit на ",", чтобы выделить отдельные названия видов, а затем снова strsplit на "", чтобы выделить названия родов:

    split.list <- sapply(strsplit(trees, split=", "), strsplit, 1, split=" ")
    split.list
    [[1]]
[[1]][[1]]
[1] "Erythrina"   "poeppigiana"


[[2]]
[[2]][[1]]
[1] "Erythrina"   "poeppigiana"

[[2]][[2]]
[1] "Juglans" "regia"   "x"       "Juglans" "nigra"  


[[3]]
[[3]][[1]]
[1] "Erythrina"   "poeppigiana"

[[3]][[2]]
[1] "Juglans" "regia"   "x"       "Juglans" "nigra"  

[[3]][[3]]
[1] "Chloroleucon" "eurycyclum"

Но тогда индексация для извлечения названий родов и рекомбинации довольно сложна (и я даже не могу это понять!). Есть ли более чистое решение для упорядоченного разделения и рекомбинации?

Также было бы приемлемо использовать тот факт, что названия родов - единственные слова, которые пишутся с заглавной буквы во всей строке. Может быть, регулярное выражение, которое вытягивает только слова с заглавными буквами?


person Kevin W    schedule 24.02.2017    source источник
comment
То, как это показано в исходном вопросе, правильно. Каждая строка в векторе может иметь переменную длину в зависимости от количества видов. Я отредактировал вопрос, чтобы прояснить его.   -  person Kevin W    schedule 24.02.2017
comment
В будущем, если возможно, это будет лучшая структура в виде списка. Как это: trees <- list(c("Erythrina poeppigiana"), c("Erythrina poeppigiana", "Terminalia amazonia"), c("Erythrina poeppigiana", "Terminalia amazonia", "Chloroleucon eurycyclum")).   -  person lmo    schedule 24.02.2017


Ответы (1)


Вот идея через Base R,

sapply(strsplit(trees, ' '), function(i) toString(i[c(TRUE, FALSE)]))
#[1] "Erythrina"    "Erythrina, Terminalia"         "Erythrina, Terminalia, Chloroleucon"

ИЗМЕНИТЬ

В дополнение к вашему комментарию для нового trees вы можете просто сделать,

sapply(strsplit(trees, ', '), function(i) toString(sub('\\s+.*', '', i)))
#[1] "Erythrina, Juglans"               "Erythrina"                       
#[3] "Erythrina, Juglans, Chloroleucon"
person Sotos    schedule 24.02.2017
comment
Это отлично работает для примера, который я привел. Я просто опробовал его на своем полном наборе данных, однако он заставил меня понять, что у меня есть некоторые виды, которые являются гибридами, которые могут быть в списке: деревья ‹- c (Juglans regia x Juglans nigra, Juglans regia x Juglans nigra, Terminalia amazonia, Juglans regia x Juglans nigra, Terminalia amazonia, Chloroleucon eurycyclum). Juglans regia x Juglans nigra в этом случае просто должны выйти как Juglans. - person Kevin W; 24.02.2017
comment
Я отредактировал исходный вопрос, включив это. Извините, я даже не догадался, что в списке есть именно эти гибриды! - person Kevin W; 24.02.2017
comment
Кажется, ваше решение работает только на примере из-за того, как в примере добавляется вид в каждый элемент. Я просто переставил элементы деревьев, и ваше решение дает тот же ответ. Попробуйте: деревья ‹- c (Erythrina poeppigiana, Juglans regia x Juglans nigra, Erythrina poeppigiana, Erythrina poeppigiana, Juglans regia x Juglans nigra, Chloroleucon eurycyclum) - person Kevin W; 24.02.2017
comment
ок, исправлю снова через несколько минут. В будущем обязательно включайте в свои примеры все угловые случаи. - person Sotos; 24.02.2017