查找没有循环

时间:2012-01-27 17:54:36

标签: r

我有两个表,我正在尝试从一个表中查找值以添加到另一个表中的值。目前我使用两个for循环,但它们运行缓慢。我是R的新手,知道我应该避免循环以加快速度,但我无法弄清楚如何。

表1(几千行,37列):

type cat1 cat2 cat3 ... cat36
   1    2    3    2         7
   3    6    2    1         9
   2    4    6    7         4
   3    5    7    8         2
   5    2    2    9         1
   4    3    1    2         3
   1    8    1    4         4
...

表2(36行,5列):

      type1 type2 type3 type4 type5
cat1      2     3     4     3     8
cat2      8     5     5     2     6
cat3      7     5     1     3     5
...
cat36     4     7     2     8     9

我想通过在Table2中添加适当的值(在5种类型和36种类别中匹配)来修改Table1中的每个值。以下是期望的结果:

type cat1 cat2 cat3 ... cat36
   1    4   11    9        11
   3   10    7    2        11
   2    7   11   12        11
   3    9   12    9         4
   5   10    8   14        10
   4    6    3    5        11
   1   10    9   11         8
...

这是我当前的(慢速)代码:

for (i in 1:36) {
    for (j in 1:nrow(Table1)) {
        Table1[j,i+1] = Table1[j,i+1] + Table2[i,Table1[j,1]]
    }
}

2 个答案:

答案 0 :(得分:4)

Table1中的type列指示要添加到Table1中的Table2中的。因此,使用“type”列作为Table2行的索引,然后转置结果矩阵,以便可以向行添加行:

Table3 <- cbind(Table1[ , "type"], 
                t(Table2[ , Table1[ , "type"] ]) + Table1[ , -1])

(我假设Table1和Table2是矩阵。如果它们是数据框,您可以使用Table1$type代替Table1[,"type"]。)

答案 1 :(得分:1)

我会将两个表转换为“long”而不是两个不同的“宽”格式。在使两个表都很长之后,您可以在两个表上执行合并(R data.frame模拟到SQL连接),然后对这些值进行简单求和。

这是一个类似的例子:

## creating some synthetic data
df1 <- data.frame(type=sample(1:4, 100, replace=TRUE), cat1=sample(1:4, 100, replace=TRUE), cat2=sample(1:4, 100, replace=TRUE),cat3=sample(1:4, 100, replace=TRUE),cat4=sample(1:4, 100, replace=TRUE) )
df2 <- data.frame(cat=1:4, type1=sample(1:4,4), type2=sample(1:4,4), type3=sample(1:4,4), type4=sample(1:4,4) )

require(reshape)

## rearrange df1
m1 <- melt(df1, id.vars="type")
m1$cat <- substr(m1$variable, 4,4)
m1$variable <- NULL

## rearrange df2
m2 <- melt(df2, id.vars="cat")
m2$type <- substr(m2$variable, 5, 5)
m2$value2 <- m2$value
m2$variable <- NULL
m2$value <- NULL

## now that they are laid out the same, they can be merged
df3 <- merge(m1, m2)
df3$newSum <- df3$value + df3$value2