数组行计算

时间:2015-10-16 15:26:26

标签: arrays r

我有下表:

DATA:

Lines <- "  ID  MeasureX    MeasureY        x1  x2  x3  x4  x5
             1      1         1             1   1   1   1   1
             2      1         1             0   1   1   1   1      
             3      1         1             1   2   3   3   3"

 DF <- read.table(text = Lines, header = TRUE, as.is = TRUE)

我想要达到的目标是:

  1. 创建5列(r1-r5)

    这是每列x1-x5与MeasureX的划分(例如x1 / measurex,x2 / measurex等)

  2. 创建5列(p1-p5)

    是每列x1-x5的分区,编号为1-5(xcolumns的数量)示例x1 / 1,x2 / 2等。

  3. MeasureY与现在无关,最终产品将是ID和列r1-r5和p1-p5,这是否可行?

    在SAS中我会选择这样的东西:

    data test6;
    set test5;
    array x {5} x1- x5;
    array r{5} r1 - r5;
    array p{5} p1 - p5;
    do i=1 to 5;
        r{i}    = x{i}/MeasureX;
        p{i} = x{i}/(i);
        end;
    

    原因在于更具动态性,因为未来列数可能会发生变化。

3 个答案:

答案 0 :(得分:2)

参数回收允许您使用常量向量进行元素分割。棘手的部分是从列名中提取数字。然后我按行数重复每个数字以执行第二次除法任务。

DF[ ,paste0("r", 1:5)] <- DF[ , grep("x", names(DF) )]/ DF$MeasureX

DF[ ,paste0("p", 1:5)] <- DF[ , grep("x", names(DF) )]/   # element-wise division
                          rep( as.numeric( sub("\\D","",names(DF)[ # remove non-digits
                                         grep("x", names(DF))]  #returns only 'x'-cols
                              ) ), each=nrow(DF) ) # make them as long as needed
#-------------
> DF
  ID MeasureX MeasureY x1 x2 x3 x4 x5 r1 r2 r3 r4 r5 p1  p2        p3   p4  p5
1  1        1        1  1  1  1  1  1  1  1  1  1  1  1 0.5 0.3333333 0.25 0.2
2  2        1        1  0  1  1  1  1  0  1  1  1  1  0 0.5 0.3333333 0.25 0.2
3  3        1        1  1  2  3  3  3  1  2  3  3  3  1 1.0 1.0000000 0.75 0.6

如果你已经知道第二个除法任务的序列向量是1-5,这可以大大简化,但这是为了允许列名的序列中的“间隙”,并仍然使用名称中的数字信息作为除数。 (你并不完全清楚这个代码将在什么情况下使用。)SAS中{r}的构造由[ , paste0('r', 1:5)]模仿。 SAS是一种宏语言,有时候有经验的用户无法弄清楚如何让R表现得像一个人。通常,需要一段时间才能失去for循环心态并开始使用R作为函数式语言。

答案 1 :(得分:2)

使用data.table包的替代方案:

cols <- names(df[c(4:8)])

library(data.table)
setDT(df)[, (paste0("r",1:5)) := .SD / df$MeasureX, by = ID, .SDcols = cols
          ][, (paste0("p",1:5)) := .SD / 1:5, by = ID, .SDcols = cols]

导致:

> df
   ID MeasureX MeasureY x1 x2 x3 x4 x5 r1 r2 r3 r4 r5 p1  p2        p3   p4  p5
1:  1        1        1  1  1  1  1  1  1  1  1  1  1  1 0.5 0.3333333 0.25 0.2
2:  2        1        1  0  1  1  1  1  0  1  1  1  1  0 0.5 0.3333333 0.25 0.2
3:  3        1        1  1  2  3  3  3  1  2  3  3  3  1 1.0 1.0000000 0.75 0.6

答案 2 :(得分:1)

你可以整理一个漂亮的循环或申请这样做,但在这里明确:

# Handling the "r" columns.
DF$r1 <- DF$x1 / DF$MeasureX
DF$r2 <- DF$x2 / DF$MeasureX
DF$r3 <- DF$x3 / DF$MeasureX
DF$r4 <- DF$x4 / DF$MeasureX
DF$r5 <- DF$x5 / DF$MeasureX

# Handling the "p" columns.
DF$p1 <- DF$x1 / 1
DF$p2 <- DF$x2 / 2
DF$p3 <- DF$x3 / 3
DF$p4 <- DF$x4 / 4
DF$p5 <- DF$x5 / 5

# Taking only the columns we want.
FinalDF <- DF[, c("ID", "r1", "r2", "r3", "r4", "r5", "p1", "p2", "p3", "p4", "p5")]

注意到这是非常简单的矩阵操作,你绝对可以在其他地方找到它。也许你是R的新手,但下次还要付出更多的努力。如果您是R的新手,那么查找一些基本的R编码教程或视频绝对值得花时间。