如何创建一个循环通过R中的列索引号的函数?

时间:2019-04-25 16:29:14

标签: r function dataframe multiple-columns

请考虑以下数据帧(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]])

我正在使用的实际数据具有更多的列,所以如果有人可以向我展示一种将该操作打包为一个函数的方法,该函数可以循环遍历列索引号并将正确的列彼此匹配,我将感到非常高兴。

1 个答案:

答案 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.然后可以按组进行操作,最后移回宽格式。