【问题标题】:Adding multiple columns, transforming with multiple variables添加多个列,使用多个变量进行转换
【发布时间】:2010-11-30 06:41:35
【问题描述】:

如何将多个变量的值相加?

如果我只有两个变量(列),我可以简单地去:

summation.variable <- variable1 + variable2

或者如果它都在一个数据框中:

transform(dataframe, summation.col = column1 + column2)

如果我有大约 10 个变量并且我不想像 col1+col2+col3+col4 那样键入每个变量,我该怎么做。更糟糕的是,我的列名称很长,有时我使用的确切列可能会改变。我有一个包含所有相关列名的字符向量,但不知道如何使用它。

以下是无用的,因为它将每行的每一列中的每个值相加,并为整个批次提供一个值。

sum(metrics)

【问题讨论】:

  • 检查第2行变量的拼写

标签: r


【解决方案1】:

回复Farrel answer

RSeek for rowProd 我找到了两个包 - matrixStatsfUtilities。你可以看看他们。

第二种解决方案有点棘手。您可以创建自己的表达式并对其进行评估。

X <- structure(list(
    varA = c(0.98, 0.75, -0.56, -1.43, 0.65, -1.15, -1.52, 0.1, 0.06, 0.76),
    varB = c(-0.12, -0.6, 0.62, 0.9, -0.44, 0.37, 0.62, 0.76, -1.61, -0.26),
    varC = c(-0.5, -0.37, -0.43, -0.7, 0.83, -0.24, -0.57, 0.05, -1.31, 0.7),
    varD = c(-0.06, -0.11, 1.03, -1.76, -0.42, -1.21, -0.62, -1, -1.16, 2.13),
    varE = c(-1.96, 0.69, -1.85, -1.74, -1.47, 1.24, 0.29, -1.18, 0.89, 0.42),
    varF = c(0.29, -0.22, -1.29, 1.19, 0.38, -0.23, -0.5, -1.07, -1.83, 0.58),
    varG = c(0.59, -0.41, -1.37, 0.89, -0.75, 0.95, 0.95, -0.9, 0.71, -1.3)
  ),
  .Names = c("varA", "varB", "varC", "varD", "varE", "varF", "varG"),
  row.names = c(NA, -10L), class = "data.frame"
)

metrics <- c("varB","varC","varF")

eval(
  parse( text = paste(metrics,collapse=" * ") ),
  envir = X
)

一些解释:

  • 粘贴创建一个看起来像 varB * varC * varF 的字符串(折叠用于连接向量的元素)
  • 解析是将文本转换为表达式
  • eval 与 envir=X 是在 X 内执行表达式

对于您的原始问题,您可以使用 collapse="+"。

编辑:如果您的变量不在 data.frame 中,那么没有 envir 的 eval 就足够了。

edit2:使用上述包中的 rowProds 的示例:

matrixStats::rowProds(as.matrix(X[,metrics])) # convert to a matrix is needed
fUtilities::rowProds(X[,metrics]) # without conversion

我在源代码中挖掘这个函数并且:

  • fUtilities 使用 apply,所以这与 apply(X,1,prod) 相同(这不是有效的解决方案)
  • matrixStats 很聪明,可以执行类似 exp(rowSums(log(X))) 的操作,因此应该更快。

速度测试:

Xm <- matrix(rnorm(50000*8),ncol=8)
Xd <- as.data.frame(Xm)

require(fUtilities)
require(matrixStats)
system.time( matrixStats::rowProds(as.matrix(Xd)) ) 
#   user  system elapsed 
#   0.08    0.02    0.09 
system.time( matrixStats::rowProds(Xm) )
#   user  system elapsed 
#   0.08    0.00    0.08 
system.time( fUtilities::rowProds(Xd) )
#   user  system elapsed 
#   0.52    0.00    0.52 

即使转换为矩阵 matrixStats 版本也更快。

【讨论】:

  • 图书馆(财富);财富(106)
  • 我想使用 do.call(f,as.list(X[,metrics])) 但我找不到像 f(a,b,c) = abc.顺便说一句,好评;)
  • prod() 做 a[1]*a[2]*...*a[n]*b[1]*b[2]*...*b[n]* c[1]*...*c[n] 所以这不是我需要的。
  • @Shane:我不同意。在对 rowProds 的帮助中,没有关于时间序列的内容,例如,有矩阵(以及适用于 data.frame 的函数)。
  • 马雷克:谢谢。你是对的:它需要一个矩阵作为输入。
【解决方案2】:

有很多方法可以进行这种操作(即跨行或列应用函数),但正如 Eduardo 指出的,应用是最基本的:

tmp <- data.frame(a=1:2,b=3:4,d=5:6)
apply(tmp, 1, prod)

这是一个非常灵活的功能。例如,您可以通过此调用同时执行这两项操作:

apply(tmp, MARGIN=1, function(x) c(sum(x), prod(x)))

跨列执行相同的分析也很简单(MARGIN 参数描述您是使用行还是列):

apply(tmp, MARGIN=2, function(x) c(sum(x), prod(x)))

【讨论】:

    【解决方案3】:

    我刚刚得到了答案。我知道我想要一些总和。我去 R 帮助查找“总和”。我在那里找到了它。 答案是按照“colSums”链接到“rowSums”。 因此,metrics 是相关列名的字符向量。以下行生成一个向量,其中所有数字都添加到每一行。

    rowSums(data.frame[metrics])
    

    如果一个人希望每个值都相乘,该怎么做?我没有看到 rowProducts。

    【讨论】:

    • 我想我会使用 apply 功能来做产品(或其他一些功能),检查 ?apply
    • rowSums 是 apply for summations 的更高效版本
    【解决方案4】:

    您想使用 rowSums(请参阅使用字符向量的索引。)

    tmp <- data.frame(a=1:2,b=3:4,d=5:6)
    rowSums(tmp[,c("a","d")])
    

    或者,更一般地说,应用:

    apply(tmp[,c("a","d")], 1, sum)
    

    【讨论】:

      猜你喜欢
      • 2015-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      • 2020-08-11
      • 1970-01-01
      • 2015-01-22
      • 1970-01-01
      相关资源
      最近更新 更多