У меня есть фрейм данных, например:
data.frame(director = c("Aaron Blaise,Bob Walker", "Akira Kurosawa",
"Alan J. Pakula", "Alan Parker", "Alejandro Amenabar", "Alejandro Gonzalez Inarritu",
"Alejandro Gonzalez Inarritu,Benicio Del Toro", "Alejandro González Iñárritu",
"Alex Proyas", "Alexander Hall", "Alfonso Cuaron", "Alfred Hitchcock",
"Anatole Litvak", "Andrew Adamson,Marilyn Fox", "Andrew Dominik",
"Andrew Stanton", "Andrew Stanton,Lee Unkrich", "Angelina Jolie,John Stevenson",
"Anne Fontaine", "Anthony Harvey"), AB = c('A', 'B', 'A', 'A', 'B', 'B', 'B', 'A', 'B', 'A', 'B', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'A'))
Как видите, некоторые записи в director
столбце представляют собой несколько имен, разделенных запятыми. Я хотел бы разбить эти записи на отдельные строки, сохранив значения другого столбца. Например, первая строка в фрейме данных выше должна быть разделена на две строки, каждая из которых имеет одно имя в director
столбце и букву «A» в AB
столбце.
Ответы:
Этот старый вопрос часто используется в качестве цели для обмана (помечен
r-faq
). На сегодняшний день на него трижды ответили, предлагая 6 различных подходов, но не хватает ориентира в качестве руководства, какой из подходов является самым быстрым 1 .Тестируемые решения включают
data.table
метода Яапа и дваdplyr
/tidyr
подхода,splitstackshape
Решение Ананды ,data.table
.Всего с помощью этого
microbenchmark
пакета было протестировано 8 различных методов на 6 различных размерах фреймов данных (см. Код ниже).Данные образца, предоставленные OP, состоят всего из 20 строк. Чтобы создать большие фреймы данных, эти 20 строк просто повторяются 1, 10, 100, 1000, 10000 и 100000 раз, что дает размер проблемы до 2 миллионов строк.
Результаты тестов
Результаты тестов показывают, что для достаточно больших кадров данных все
data.table
методы работают быстрее, чем любой другой метод. Для фреймов данных, содержащих более 5000 строк,data.table
метод 2 и вариант ЯапаDT3
являются самыми быстрыми, на порядок быстрее, чем самые медленные методы.Примечательно, что синхронизация двух
tidyverse
методов иsplistackshape
решения настолько схожа, что трудно различить кривые на графике. Это самые медленные из протестированных методов для всех размеров фреймов данных.Для небольших фреймов данных базовое решение Мэтта R и
data.table
метод 4, похоже, имеют меньше накладных расходов, чем другие методы.Код
Определите функцию для эталонных прогонов размера проблемы
n
Запустите тест для разных размеров проблем
Подготовить данные для построения графика
Создать диаграмму
Информация о сеансе и версии пакета (отрывок)
1 Мое любопытство было задето этим обильным комментарием Brilliant! На порядки быстрее! на
tidyverse
ответ на вопрос, который был закрыт как дубликат этого вопроса.источник
data.table
,dplyr
и т.д.strsplit
fixed=TRUE
. Поскольку это есть у другого, это повлияет на тайминги. Так как R 4.0.0 , по умолчанию, при созданииdata.frame
, являетсяstringsAsFactors = FALSE
, таким образомas.character
может быть удален.Несколько альтернатив:
1) два способа с Таблица данных:
2) а dplyr / тидир комбинация:
3) с тидиртолько: с
tidyr 0.5.0
(и более поздними версиями) вы также можете просто использоватьseparate_rows
:Вы можете использовать
convert = TRUE
параметр для автоматического преобразования чисел в числовые столбцы.4) с основанием R:
источник
data.table(id= "X21", a = "chr1;chr1;chr1", b="123;133;134",c="234;254;268")
становлениеdata.table(id = c("X21","X21",X21"), a=c("chr1","chr1","chr1"), b=c("123","133","134"), c=c("234","254","268"))
?setDT(dt)[,lapply(.SD, function(x) unlist(tstrsplit(x, ";",fixed=TRUE))), by = ID]
это то, что сработало для меня.Называя ваш исходный data.frame
v
, мы получаем следующее:Обратите внимание на использование
rep
для создания нового столбца AB. Здесьsapply
возвращается количество имен в каждой из исходных строк.источник
vapply
? Есть ли здесь что-нибудьvapply
более подходящее?sapply(s, length)
можно заменить наlengths(s)
.Поздно, но другая обобщенная альтернатива - использовать
cSplit
из моего пакета "splitstackshape", у которого естьdirection
аргумент. Установите это значение,"long"
чтобы получить указанный вами результат:источник
источник
Другой контрольный показатель в результате , используя
strsplit
из базы в настоящее время может быть рекомендованы разделить запятую строк в столбце в отдельные строки , так как он был самым быстрым в широком диапазоне размеров:Обратите внимание, что использование
fixed=TRUE
существенно влияет на тайминги.Сравниваемые методы:
Библиотеки:
Данные:
Результаты вычислений и хронометража:
Обратите внимание, такие методы, как
вернуть
strsplit
дляunique
директора и может быть сопоставимо сно, насколько я понимаю, об этом не спрашивали.
источник