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

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

   m f
A 40 NA
B 40 20
C NA 50

目标是通过使用分配给矩阵中每个类别的相应值来乘以 DF$credit 中的值,例如,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 基础包来执行此操作,但我愿意接受任何可以很好地工作的有用解决方案。

4

3 回答 3

3

您可以通过使用和制作索引矩阵来构造一组索引derived(作为您的派生矩阵)。存在的原因是因为和是因素,而我只想要字符索引。DF$groupDF$genderas.characterDF$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作为一个因素,而是作为一个数字。

于 2011-12-21T00:13:31.367 回答
2

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

只需使用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)
于 2011-12-21T00:15:05.003 回答
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
于 2011-12-21T00:16:58.877 回答