请考虑以下数据帧(df):
fc3
我想创建一个新列,该列显示两个对应列之间的乘积之和。为了编写更少的代码,我通过列的索引号来寻址列。不幸的是,我没有编写函数的经验,因此我最终手动完成了此工作,这非常繁琐且不太优雅。
以下是可重复的数据框示例,以及我到目前为止尝试过的示例:
"id" "a1" "b1" "c1" "not_relevant" "p_a1" "p_b1" "p_c1"
a 2 6 0 x 2 19 12
a 4 2 7 x 3.5 7 11
b 1 9 4 x 7 1.5 4
b 7 5 11 x 8 12 5
这可以达到预期的结果,但是正如我提到的那样,效率不是很高:
id <- c("a","a","b","b")
df <- data.frame(id)
df$a1 <- as.numeric((c(2,4,1,7)))
df$b1 <- as.numeric((c(6,2,9,5)))
df$c1 <- as.numeric((c(0,7,4,11)))
df$not_relevant <- c("x","x","x","x")
df$p_a1 <- as.numeric((c(2,3.5,7,8)))
df$p_b1 <- as.numeric((c(19,7,1.5,12)))
df$p_c1 <- as.numeric((c(12,11,4,5)))
require(dplyr)
df %>% mutate(total = .[[2]]*.[[6]] + .[[3]] *.[[7]]+ .[[4]] *.[[8]])
我正在使用的实际数据具有更多的列,所以如果有人可以向我展示一种将该操作打包为一个函数的方法,该函数可以循环遍历列索引号并将正确的列彼此匹配,我将感到非常高兴。
答案 0 :(得分:1)
列索引不是执行此操作的好方法。 (通常不是一个好方法...)
这是一个简单的dplyr
方法,该方法假定列以正确的对应顺序排列(也就是说,如果"x1", "x2", "x3"
的顺序与"p_x3", "p_x2", "p_x1"
的顺序不同,则会给出错误的结果)。您可能还需要针对实际数据优化选择标准:
df$total = rowSums(select(df, starts_with("x")) * select(df, starts_with("p_")))
df
# id x1 x2 x3 not_relevant p_x1 p_x2 p_x3 total
# 1 a 2 6 0 x 2.0 19.0 12 118.0
# 2 a 4 2 7 x 3.5 7.0 11 105.0
# 3 b 1 9 4 x 7.0 1.5 4 36.5
# 4 b 7 5 11 x 8.0 12.0 5 171.0
另一种不错的选择是将数据转换为长格式,其中您有一个x
列和一个p
列,并带有一个“ index”列,分别表示1、2 ,3.然后可以按组进行操作,最后移回宽格式。