【问题标题】:Divide each data frame row by vector in R将每个数据帧行除以 R 中的向量
【发布时间】:2012-11-29 15:20:01
【问题描述】:

我正在尝试将具有 16 列的数据框中的每个数字除以每列的特定数字。这些数字存储为一个数据帧,其中 1-16 对应于较大数据帧第 1-16 列中的样本。每列有一个数字,我需要将其除以更大的电子表格中的每个数字,然后将输出打印到最终的电子表格中。

这是我开始的示例。要分割的电子表格。

            X131.478.1 X131.478.2 X131.NSC.1 X131.NSC.2 X166.478.1 X166.478.2
1/2-SBSRNA4          4          2          2          6          7          6
A1BG                93         73         88         86         58         65
A1BG-AS1           123        103         96        128         46         57

将电子表格除以的数字

X131.478.1 1.0660880
X131.478.2 0.9104053
X131.NSC.1 0.8642545
X131.NSC.2 0.9611866
X166.478.1 0.9711406
X166.478.2 1.0560121

以及预期的结果,不一定像我在这里所做的那样四舍五入。

    X131.478.1 X131.478.2 X131.NSC.1 X131.NSC.2 X166.478.1 X166.478.2
1/2-SBSRNA4          3.75          2.19          2.31          6.24          7.20         5.68
A1BG                87.23         80.17         101.82         89.47         59.72         61.55
A1BG-AS1           115.37        113.13         111.07        133.16         47.36         53.97

我尝试简单地划分数据帧 mx2 = mx/sf,其中 mx 是大数据集,sf 是要除以的数字数据帧。这似乎将所有内容除以 sf 数据集中的第一个数字。

除法的数字由estimateSizeFactors 生成,它是DESeq 包的一部分,如果有帮助的话。

任何帮助都会很棒。谢谢!

【问题讨论】:

  • 这不过是矩阵乘以向量;看我的回答。

标签: r vector dataframe divide


【解决方案1】:

sweep 对于这类操作很有用,但它需要一个矩阵作为输入。因此,将您的数据框转换为矩阵,执行操作然后转换回来。例如,一些虚拟数据,我们将矩阵mat的各个列中的每个元素除以向量vec中的相应值:

mat <- matrix(1:25, ncol = 5)
vec <- seq(2, by = 2, length = 5)

sweep(mat, 2, vec, `/`)

在使用中我们有:

> mat
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25
> vec
[1]  2  4  6  8 10
> sweep(mat, 2, vec, `/`)
     [,1] [,2]     [,3]  [,4] [,5]
[1,]  0.5 1.50 1.833333 2.000  2.1
[2,]  1.0 1.75 2.000000 2.125  2.2
[3,]  1.5 2.00 2.166667 2.250  2.3
[4,]  2.0 2.25 2.333333 2.375  2.4
[5,]  2.5 2.50 2.500000 2.500  2.5
> mat[,1] / vec[1]
[1] 0.5 1.0 1.5 2.0 2.5

要从数据框转换,请使用 as.matrix(df)data.matrix(df),反之则使用 as.data.frame(mat)

【讨论】:

  • 这不过是矩阵乘以向量;看我的回答。
  • 这不适用于数据框,这是问题所要求的。
  • @Bowecho 将这些操作转换为矩阵非常简单,并且确实需要,因为对数据帧执行这样的操作很慢。
【解决方案2】:

假设我们有一个数据框,df:

> df
  a b   c
1 1 3 100
2 2 4 110

我们想用相同的向量来划分每一行,vec

> vec <- df[1,]
> vec
  a b   c
1 1 3 100

那么我们可以使用mapply如下:

> mapply('/', df, vec)
     a        b   c
[1,] 1 1.000000 1.0
[2,] 2 1.333333 1.1

【讨论】:

    【解决方案3】:

    为了多样化,你也可以使用mapply

    mx <- structure(list(X131.478.1 = c(4L, 93L, 123L), X131.478.2 = c(2L, 
    73L, 103L), X131.NSC.1 = c(2L, 88L, 96L), X131.NSC.2 = c(6L, 
    86L, 128L), X166.478.1 = c(7L, 58L, 46L), X166.478.2 = c(6L, 
    65L, 57L)), .Names = c("X131.478.1", "X131.478.2", "X131.NSC.1", 
    "X131.NSC.2", "X166.478.1", "X166.478.2"), class = "data.frame", row.names = c("1/2-SBSRNA4", 
    "A1BG", "A1BG-AS1"))
    
    sf <- structure(list(V1 = c(1.066088, 0.9104053, 0.8642545, 0.9611866, 
    0.9711406, 1.0560121)), .Names = "V1", row.names = c("X131.478.1", 
    "X131.478.2", "X131.NSC.1", "X131.NSC.2", "X166.478.1", "X166.478.2"
    ), class = "data.frame")
    
    
    mapply(function(x, y) x * y, mx, t(sf))
    
    
        X131.478.1 X131.478.2 X131.NSC.1 X131.NSC.2 X166.478.1 X166.478.2
    [1,]   4.264352   1.820811   1.728509    5.76712   6.797984   6.336073
    [2,]  99.146184  66.459587  76.054396   82.66205  56.326155  68.640787
    [3,] 131.128824  93.771746  82.968432  123.03188  44.672468  60.192690
    

    但我认为 Josh 的答案更好……而 Gavin 的更好!

    【讨论】:

      【解决方案4】:

      这不过是逐元素矩阵乘法

      mat <- matrix(c(4,2,2,6,7,6, 93,73,88,86,58,65, 123,103,96,128,46,57), nrow=3, byrow=T)
      
      vec = c(1.0660880,0.9104053,0.8642545,0.9611866,0.9711406,1.0560121)
      
      mat %o% 1/vec
      
                 [,1]      [,2]       [,3]       [,4]      [,5]      [,6]
      [1,]   3.752035  2.080761   1.876018   6.242284  6.566062  6.242284
      [2,] 102.152305 75.169342  96.660246  88.555663 63.707889 66.931606
      [3,] 142.319190 97.536761 111.078392 121.210732 53.225063 53.976654
      

      为此,我们使用了outer-product approach,因为直接尝试mat %*% 1/vecnon-conformable arguments 上会出错,因为它们具有不同的形状。 或者看看https://stackoverflow.com/search?q=%5Br%5D+multiply+matrix+by+vector上的很多帖子

      【讨论】:

      • 您的输出与 OP 的预期输出不匹配。
      • @oshun:废话,你说得对,这是逐元素乘法(/除法)。我必须让%*% 方法起作用。
      【解决方案5】:

      你可以使用transform

      mx2 <- transform(mx, 
          X131.478.1=X131.478.1/sf["X131.478.1",1],
          X131.478.2=X131.478.2/sf["X131.478.2",1],
          etc
      )
      

      用 16 列输入有点多,但应该可以。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-22
        • 2021-03-04
        相关资源
        最近更新 更多