按矢量,按行而不是按列划分数据帧

Gim*_*ist 3 r

我有这个数据框和向量,我想用以下行划分行:

div <- c(10,100,1000)
df <- as.data.frame(matrix(rep(1,9),nrow=3))
df <- cbind(type = as.factor(c("A","B","C")),df)
> df
  type V1 V2 V3
1    A  1  1  1
2    B  1  1  1
3    C  1  1  1
Run Code Online (Sandbox Code Playgroud)

我希望以数据框形式给出答案,并保留原因.将它与向量分开时,我得到了"错误"的答案:

df1 <- cbind(df[,1], df[,-1]/div)
> df1
  df[, 1]    V1    V2    V3
1       A 0.100 0.100 0.100
2       B 0.010 0.010 0.010
3       C 0.001 0.001 0.001
Run Code Online (Sandbox Code Playgroud)

我希望每行除以向量,而不是每列.

我的解决方法是:

divfun <- function(x){
  x / div
}

df2 <- cbind(df[,1], t(apply(df[,-1], 1, divfun)))
> df2
        V1   V2    V3
[1,] 1 0.1 0.01 0.001
[2,] 2 0.1 0.01 0.001
[3,] 3 0.1 0.01 0.001
Run Code Online (Sandbox Code Playgroud)

请注意,这些因素现在已丢失.

这里有两个问题:

  1. 是否有一种更简单的方法可以做到这一点,而不是为它做一个新的功能?
  2. 假设没有更简单的方法,我的因素A,B和C发生了什么?我猜它与胁迫矩阵有关(因为t())?

Rei*_*son 7

您正在寻找的功能是sweep():

sweep(df[, -1], MARGIN = 2, div, FUN = "/")

> sweep(df[, -1], MARGIN = 2, div, FUN = "/")
   V1   V2    V3
1 0.1 0.01 0.001
2 0.1 0.01 0.001
3 0.1 0.01 0.001
Run Code Online (Sandbox Code Playgroud)

于是

cbind(type = df[,1], sweep(df[, -1], 2, div, FUN = "/"))

> cbind(type = df[,1], sweep(df[, -1], 2, div, FUN = "/"))
  type  V1   V2    V3
1    A 0.1 0.01 0.001
2    B 0.1 0.01 0.001
3    C 0.1 0.01 0.001
Run Code Online (Sandbox Code Playgroud)

获得所需的输出.

请注意,在这里,参数MARGIN不像它一样引用rows(1)或columns(2)apply().在sweep()它中指的是数组的边距,对应于STATS你希望扫出的矢量(在这种情况下除以).换句话说,STATS(div在您的情况下)的第一个元素是从第1列扫出的值,第二个元素STATS是从第2列扫出的值,依此类推.