умножение столбцов в R
Как мне создать два дополнительных столбца «1» и «2» путем обобщенного умножения 1.x * 1.y и 2.x * 2.y?
Я пытаюсь получить обобщенное решение, в котором количество столбцов может быть слишком большим. Итак, я хочу умножить все x на все y. Хотя x и y фиксированы, n нужно вычислить из кадра данных.
Для простоты предположим, что n также фиксировано, но это большое число.
Я могу попробовать следующее:
abc[,c(6,7)]=abc[,c(2,3)]*abc[,c(4,5)] Это будет работать только в том случае, если позиции столбцов смежны. Для меня этого достаточно. Если у кого-то может быть более общее решение, оно принесет пользу всем нам.
2 ответа
Если нужно умножить только пару переменных, мы можем сделать это с помощью transform , умножив интересующие столбцы
Если у нас много столбцов, то один из подходов — split набор данных в list data.frames, взяв подстроку имен, а затем перебрав list и умножив строки с do.call
Или другой вариант (на основе попарного умножения столбцов)
Mutate сохранит исходные переменные. Mutate_all позволит вам умножить все столбцы в вашем фрейме данных.
умножьте два разных data.frames на новый data.frame с новыми заголовками столбцов из входного столбца
Я хотел бы умножить несколько столбцов из определенного кадра data.frame * df1 * на проценты, соответствующие заголовкам столбцов в * df1 * . Они приведены в data.frame df2, столбец 1, который называется ID. Я хочу, чтобы результат был как в df3.
Обратите внимание, что мой набор данных большой. В df1 13 000 строк и 33 столбца. В df2 136 строк и 3 столбца.
Эффективное умножение столбцов во фрейме данных
У меня есть большой фрейм данных, в котором я умножаю два столбца, чтобы получить еще один столбец. Сначала я запускал цикл for, например:
но это занимает 9 дней.
Другой альтернативой было plyr , и я действительно мог неправильно использовать переменные:
но это навсегда
задан 10 сен ’12, 19:09
Что случилось с df$new_column <- df$column1 * df$column2 ? Насколько велик ваш фрейм данных? — Blue Magister
400000 строк должны быть быстрыми даже с plyr . но если вы просто пытаетесь умножить два столбца, у @BlueMagister есть лучшее решение. Тем не менее, версия цикла for не должна занимать 9 дней. — Justin
Большинство операций в R векторизованы, поэтому вы можете умножать векторы на векторы, и они будут умножать записи одного и того же индекса вместе. Проблема с циклом for заключается в том, что R создает новый фрейм данных для каждой итерации цикла. Предложенное мной решение создает только один новый фрейм данных вместо 400 XNUMX новых фреймов данных. — Blue Magister
«Экономичный по времени» и «plyr» обычно не используются в одном предложении. Если ваша цель — скорость, обратите внимание на пакет data.table. (. хотя 400K x 7 — это крошечный набор данных в наши дни, и обычных функций, которые вам были предложены в ответах ниже, должно быть достаточно.) — IRTFM
Причина, по которой plyr работает так медленно, заключается в том, что вы без необходимости группируете по столбцу1 и столбцу2. Это создает группы для каждой уникальной комбинации этих столбцов. ddply не требуется. data.table эффективно создаст новый столбец. — mnel
5 ответы
Как сказал Blue Magister в комментариях,
должно работать нормально. Конечно, мы никогда не сможем знать наверняка, если у нас нет примера данных.
Еще красивее, но по сути то же самое: df$new_column <- with( df , column1 * column2) — ИРТФМ
@DWin, который кажется немного странным в использовании with() но затем выполните назначение через $<- . Что-то не так с within() or transform()? — Гэвин Симпсон
Если вы назначаете только один (новый или другой) столбец, я думаю, вам нужно использовать with вместо within , потому как within вернет весь data.frame. Во всяком случае, это мое понимание. (. и тестирование подтверждает, что dat$new <- внутри(dat, old*2) приведет к беспорядочному копированию копии вложенного фрейма данных в объекте ‘dat’. — ИРТФМ
Да должно работать нормально для набора данных размером 20 МБ (400 тыс. x 7 строк). Но он скопирует все 20 МБ, поэтому не повторяйте слишком много. Например, добавление 10 столбцов с помощью $<- каждый раз нужно 400мб( 400e3*sum(7:17)*8/1024^2 ). Добавление 50 оттоков через 5 ГБ ( 400e3*sum(7:57)*8/1024^2 ), чтобы получить результат 400k x 57 (всего 173 МБ). Просто чтобы быть в курсе. — Мэтт Доул
Итак, добавляйте столбцы сразу, если можете, а не один за другим. Так как это может кусаться даже при размере 20 МБ. На всякий случай, если это будет вашим следующим шагом. Или используйте := который не копирует все 20 МБ. — Мэтт Доул
A data.table решение позволит избежать большого количества внутреннего копирования, имея при этом преимущества, заключающиеся в том, что код не разбрызгивается $ .
Незначительная, несколько менее эффективная версия ответа Саши заключается в использовании transform() or within()
(Я ненавижу забрызгивать свой пользовательский код $ .)
Почему это будет менее эффективно? Является $<- оптимизирован, чтобы не копировать фрейм данных? — Габор Чарди
Недавно были проведены некоторые оптимизации определенных операций над фреймами данных, но не помните, является ли это одной из них. Я предполагаю, что это будет немного менее эффективно, потому что transform() и within() содержат довольно много дополнительных строк кода R поверх той, которая вычисляет выражение. — Гэвин Симпсон
@GaborCsardi К сожалению, $<- не оптимизирован, чтобы не копировать в R; он копирует весь df . Как делает transform и within ; они копируют весь df слишком. Вот почему data.table введены := , чтобы разрешить назначение по ссылке, как показано в ответе mnel. — Мэтт Доул
@GavinSimpson Все решения, кроме := скопировать весь df , поэтому не масштабируйте. Дополнительные строки кода в transform и within крошечные в сравнении. Если вызов не зациклен, например, в transform -группой, но тогда еще больше преобладают все копии. Если transform не копия становятся в него войдет количество строк. — Мэтт Доул
@MatthewDowle Вряд ли это большая проблема, и простое правильное использование базовых решений R сэкономит OP огромное количество времени. Я согласен, что переход на data.table для этих вещей окупится с лихвой, но это дополнительный набор функций и синтаксиса, которые нужно освоить. Мне не нужно продаваться за совершенство data.table; Я уже расписался в том сборнике гимнов. Мне просто нужно немного больше времени, чтобы интегрировать его в мой рабочий процесс, чтобы синтаксис закрепился. — Гэвин Симпсон
Вы можете просто создать функцию для обработки всех видов умножений, подобных этому:
Умножить строки одного датафрейма на столбцы другого по условию
1.добавить условие проверки, является ли в текущей строчке столбец ‘v6’ датафрейма main_df равным названию столбца датафрейма full
2. Если условие выполняется, то умножить каждый столбец текущей строчки main_df на соответствующее значение 1 строки full
Т.е если main_df[‘v6’]= столбцу col1 (из full), то каждое значения от v1 до v5 Умножаем на 2 (ведь col1 в 1 строке имеет значение 2).
И так далее.
3. После Умножения всех значений main_df , найти сумму каждого столбца
в идеале было бы хорошо, если бы можно было указывать для какой строчки full будет идти умножение, но по-умолчанию на 1-ую.
В итоге должно получиться: