Добавление нескольких столбцов, преобразование с несколькими переменными - PullRequest
5 голосов
/ 22 сентября 2009

Как мне добавить значения из многих переменных?

Если бы у меня было только две переменные (столбцы), я мог бы просто перейти:

summation.variable <- variable1 + variable2

или, если все это было в кадре данных:

transform(dataframe, summation.col = column1 + column2)

Как мне это сделать, если у меня около 10 переменных, и я не хочу вводить каждую, как в col1 + col2 + col3 + col4. Что еще хуже, мои столбцы имеют довольно длинные имена, и иногда точные столбцы, которые я использую, могут измениться. У меня есть символьный вектор со всеми соответствующими именами столбцов, но я не могу думать, как его использовать.

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

sum(metrics)

Ответы [ 4 ]

8 голосов
/ 22 сентября 2009

Вы хотите использовать rowSums (см. Индексирование с символьным вектором)

tmp <- data.frame(a=1:2,b=3:4,d=5:6)
rowSums(tmp[,c("a","d")])

или, в более общем случае, применимо:

apply(tmp[,c("a","d")], 1, sum)
4 голосов
/ 22 сентября 2009

Существует много способов выполнить операцию такого типа (т. Е. Применить функцию к строке или столбцу), но, как указывает Эдуардо, применять - это самый простой:

tmp <- data.frame(a=1:2,b=3:4,d=5:6)
apply(tmp, 1, prod)

Это очень гибкая функция. Например, вы можете выполнить обе операции одновременно с помощью этого вызова:

apply(tmp, MARGIN=1, function(x) c(sum(x), prod(x)))

Выполнение одного и того же анализа по столбцам также просто (параметр MARGIN описывает, используете ли вы строки или столбцы):

apply(tmp, MARGIN=2, function(x) c(sum(x), prod(x)))
3 голосов
/ 22 сентября 2009

Отвечая на Farrel ответ :

Вкл. RSeek для rowProd Я нашел два пакета - matrixStats и fUtilities . Вы можете посмотреть на них.

Второе решение немного сложнее. Вы можете создать свое выражение и оценить их.

X <- structure(list(
    varA = c(0.98, 0.75, -0.56, -1.43, 0.65, -1.15, -1.52, 0.1, 0.06, 0.76),
    varB = c(-0.12, -0.6, 0.62, 0.9, -0.44, 0.37, 0.62, 0.76, -1.61, -0.26),
    varC = c(-0.5, -0.37, -0.43, -0.7, 0.83, -0.24, -0.57, 0.05, -1.31, 0.7),
    varD = c(-0.06, -0.11, 1.03, -1.76, -0.42, -1.21, -0.62, -1, -1.16, 2.13),
    varE = c(-1.96, 0.69, -1.85, -1.74, -1.47, 1.24, 0.29, -1.18, 0.89, 0.42),
    varF = c(0.29, -0.22, -1.29, 1.19, 0.38, -0.23, -0.5, -1.07, -1.83, 0.58),
    varG = c(0.59, -0.41, -1.37, 0.89, -0.75, 0.95, 0.95, -0.9, 0.71, -1.3)
  ),
  .Names = c("varA", "varB", "varC", "varD", "varE", "varF", "varG"),
  row.names = c(NA, -10L), class = "data.frame"
)

metrics <- c("varB","varC","varF")

eval(
  parse( text = paste(metrics,collapse=" * ") ),
  envir = X
)

Некоторые объяснения:

  • вставить создать строку, похожую на varB * varC * varF (свернуть для объединения элементов вектора)
  • синтаксический анализ для преобразования текста в выражение
  • eval с envir = X - выполнить выражение в X

Для исходного вопроса вы можете использовать collapse = "+".

edit: если ваши переменные не находятся в data.frame, тогда достаточно eval без envir.

edit2: примеры использования rowProds из упомянутых пакетов:

matrixStats::rowProds(as.matrix(X[,metrics])) # convert to a matrix is needed
fUtilities::rowProds(X[,metrics]) # without conversion

Я копаю в источнике эту функцию и:

  • Использование утилит применяется, так же как и применение (X, 1, prod) (это не эффективный прием)
  • matrixStats умный и делает что-то вроде exp (rowSums (log (X))), поэтому должен быть быстрее.

Скоростные испытания:

Xm <- matrix(rnorm(50000*8),ncol=8)
Xd <- as.data.frame(Xm)

require(fUtilities)
require(matrixStats)
system.time( matrixStats::rowProds(as.matrix(Xd)) ) 
#   user  system elapsed 
#   0.08    0.02    0.09 
system.time( matrixStats::rowProds(Xm) )
#   user  system elapsed 
#   0.08    0.00    0.08 
system.time( fUtilities::rowProds(Xd) )
#   user  system elapsed 
#   0.52    0.00    0.52 

Даже с преобразованием в матрицу MatrixStats версия работает быстрее.

1 голос
/ 22 сентября 2009

Я только что получил ответ. Я знал, что хочу какую-то сумму. Я пошел в помощь R, чтобы найти «сумму». И там я нашел это. Ответ заключается в переходе по ссылке «colSums» на «rowSums». Так, где метрика - это символьный вектор имен соответствующих столбцов. Следующая строка создает вектор, в котором все числа добавляются в каждую строку.

rowSums(data.frame[metrics])

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...