使用数组结果作为原始数据帧的乘数

时间:2011-12-20 23:52:08

标签: arrays r matrix dataframe r-factor

对于给定的数据帧,我想将数组的值乘以数据帧的列。数据框由行组成,包含名称,数值和两个因子值:

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

此外,我们有一个从数据框派生的矩阵(在更复杂的情况下,这将是一个数组)。该矩阵包含属于特定类别的所有合约的总和值(以m / f和A / B / C为特征):

   m f
A 40 NA
B 40 20
C NA 50

目标是通过使用分配给矩阵中每个类别的相应值,将DF $信用值中的值相乘,例如: DF中第一行的值10将乘以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 base软件包执行此操作,但我愿意为任何有用的解决方案做好准备。

3 个答案:

答案 0 :(得分:3)

您可以通过从derivedDF$group中创建索引矩阵,将一组索引构建到DF$gender(作为派生矩阵)。 as.character存在的原因是因为DF$groupDF$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作为因素,而是数字。

答案 1 :(得分:2)

当你创建data.frame对象时,不要使用cbind,它不是必需的,它会强制信用变量成为一个因素。

只需使用DF <- data.frame(name, credit, gender, group)

即可

然后运行一个遍历data.frame对象中每一行的for循环。

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)

答案 2 :(得分: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