根据名称有条件地乘以值

时间:2019-11-11 10:19:09

标签: r dplyr

我有一个数据框,类似于:

d <-
  data.frame(
    col1 = c(7, 8, 9),
    col2 = c(12, 7, 0),
    col3 = c(1, 2, 3)
  )

和带有数字的向量

coefs <-
  c(
    col1  = 4,
    col2  = 6
  )

我需要实现的是,如果df中的列名等于向量列,那么我想乘以它。如果列名不同,丢失或不相等,则应保持不变。

例如,对于上述数据帧和向量,结果应为:

result <-
  data.frame(
    col1 = c(28, 32, 36),
    col2 = c(72, 42, 0),
    col3 - c(1, 2, 3)
  )

我认为最好的方法是使用mutate_if,但是我不确定如何匹配列名。

3 个答案:

答案 0 :(得分:6)

您可以直接在基数R中执行此操作

d[names(coefs)] <- d[names(coefs)] * as.list(coefs)
d

#  col1 col2 col3
#1   28   72    1
#2   32   42    2
#3   36    0    3

答案 1 :(得分:2)

您还可以使用sweep()中的base R

d[names(coefs)] <- sweep(d[names(coefs)], 2, FUN = "*", coefs)

  col1 col2 col3
1   28   72    1
2   32   42    2
3   36    0    3

通常,dplyr对于这些类似扫描的操作并不是很好。这是因为它没有像预期的那样对每列应用一个值,而是对这些值进行了回收。为了说明这一点:

d %>%
 mutate_at(vars(names(coefs)), ~ . * coefs)

  col1 col2 col3
1  112  288    1
2  192  252    2
3  144    0    3

您会看到第一列是28 * 4、32 * 6,然后是36 * 4。

答案 2 :(得分:1)

以下是进行繁重工作的好方法:

for (i in colnames(d)) {
  if (any(names(coefs) %in% i)) {
    d[, i] <- d[, i] * coefs[i]
  }
}

> d
  col1 col2 col3
1   28   72    1
2   32   42    2
3   36    0    3