2011-12-20 1 views
1

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

name credit gender group 
n1 10 m A 
n2 20 f B 
n3 30 m A 
n4 40 m B 
n5 50 f C 

Этот кадр данных может быть создан с помощью команд:

name <- c('n1','n2','n3','n4','n5') 
credit <- c(10,20,30,40,50) 
gender <- c('m','f','m','m','f') 
group <- c('A','B','A','B','C') 
DF  <-data.frame(cbind(name,credit,gender,group)) 
# binds columns together and uses it as a data frame 

Кроме того, мы матрица, полученные из кадр данных (в более сложных случаях это будет массив). Эта матрица содержит значение суммы всех контрактов, которые попадают в особую категорию (характеризуется м/ж и A/B/C):

m f 
A 40 NA 
B 40 20 
C NA 50 

Цель состоит в том, чтобы умножить значения в DF $ кредита, используя соответствующее значение, присвоенное каждой категории в матрице, например значение 10 первой строки в DF будет умножено на 40 (категория, определяемая m и A).

Результат будет выглядеть так:

name credit gender group result 
n1 10 m A 400 
n2 20 f B 400 
n3 30 m A 1200 
n4 40 m B 1600 
n5 50 f C 2500 

Если возможно, я хотел бы выполнить это с помощью R базового пакета, но я открыт для любых полезных решений, которые работают хорошо.

ответ

3

Вы можете построить набор индексов в derived (являясь вашей производной матрицей), сделав индексную матрицу из DF$group и DF$gender. Причина в том, что as.character есть потому, что DF$group и DF$gender являются факторами, тогда как мне просто нужны индексы символов.

>idx = matrix(c(as.character(DF$group),as.character(DF$gender)),ncol=2) 
>idx 
[,1] [,2] 
[1,] "A" "m" 
[2,] "B" "f" 
[3,] "A" "m" 
[4,] "B" "m" 
[5,] "C" "f" 
>DF$result = DF$credit * derived[idx] 

Отмечает с этой последней строкой, используя код, который вы имеете выше генерировать DF ваши числовые столбцы оказываются как факторы (т.е. DF$credit является фактором). В этом случае вам нужно сделать as.numeric(DF$credit)*derived[idx]. Однако я полагаю, что в ваших фактических данных ваш фрейм данных не имеет DF$credit как фактор, а вместо этого как числовой.

+0

+1 для поиска матрицы. Но ... Если он использовал 'cbind', прежде чем он использовал data.frame, тогда все было« character », а' data.frame' в своих настройках по умолчанию превратили все это в фактор. Поэтому нужно иметь 'as.numeric (as.character (...)) 'лечение, чтобы получить правильные результаты. –

+0

Спасибо за ваш вклад. Я знаю, что as.numeric (...) должен применяться к кредиту DF $. Например, ваш ответ работает очень хорошо. Я попытаюсь проверить, если для более сложных случаев, в которых производным объектом является массив. – John

2

Когда вы создаете объект data.frame, не используйте cbind, это необязательно, и это заставляет кредитную переменную стать фактором.

Просто используйте DF <- data.frame(name, credit, gender, group)

Затем запустить цикл, который проходит через каждую строку в вашем объекте data.frame.

n <- length(DF$credit) 
result <- rep(0, n) 
for(i in 1:n) { 
    result[i] <- DF$credit[i] * sum(DF$credit[DF$gender==DF$gender[i] & DF$group==DF$group[i]]) 
} 

Замените свой объект data.frame новым, который включает в себя ваши результаты.

DF <- data.frame(name, credit, gender, group, result) 
+0

Это не 'cbind', который приводит к сомнению. Он подходит к режиму «характер». Это функция 'data.frame', которая имеет значение по умолчанию' strAsAsFactors = TRUE', которое будет принуждать все векторы символов к факторам. –

+0

Это третий метод, который также дает правильный результат для данных примера. Спасибо за ваш вклад! – John

2

Я рекомендую plyr пакет, но вы можете сделать это с помощью базового by функции:

> by(DF, DF['name'], function (row) row$credit * m[as.character(row$group), as.character(row$gender)]) 
name: n1 
[1] 400 
--------------------------------------------------------------------- 
name: n2 
[1] 400 
--------------------------------------------------------------------- 
name: n3 
[1] 1200 
--------------------------------------------------------------------- 
name: n4 
[1] 1600 
--------------------------------------------------------------------- 
name: n5 
[1] 2500 

plyr может дать вам результат в виде кадра данных, и это приятно:

> ddply(DF, .(name), function (row) row$credit * m[as.character(row$group), as.character(row$gender)]) 
    name V1 
1 n1 400 
2 n2 400 
3 n3 1200 
4 n4 1600 
5 n5 2500 
+0

+1 'plyr', я бы порекомендовал его, но для OP предпочтительнее база R.' ddply' является потрясающе! –

+0

Уважаемый Даниэль, спасибо за ваш пример. Я попробовал функцию by, которая создает список. С предположением, что «m» означает производную матрицу, я мог бы заставить ее работать (небольшое описание того, что делает ваш код, стало бы намного легче понять). Когда у меня будет больше времени, я также рассмотрю пакет plyr. – John

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

  • Нет связанных вопросов^_^