在选择列之间循环应用列的功能

时间:2018-11-07 20:25:18

标签: r function for-loop

数据:

dat <- data.frame(id = "T2", Height = 1.2, 
              Number_2 = 1, node_age_2 = 0, 
              Number_3 = 1, node_age_3 = 1, 
              Number_4 = 1, node_age_4 = 2)

我需要遍历此数据框,并应用一系列复杂的功能。我不确定遍历每一列以及如何实现。我设想的步骤是:

  1. 从最低值列Number_2:node_age_2
  2. 开始
  3. 应用功能Answer_2 = Number_2 + node_age_2
  4. 应用功能Answer_3 = Number_3 + node_age_3
  5. if (Answer_3 < Answer_2){Answer_3} ELSE {Answer_2}
  6. 按顺序继续数据帧的结尾。

最后,最终产品将类似于:

id Height Number_2 node_age_2 Answer_2 Number_3 node_age_3 Answer_3 Number_4 node_age_4 Answer_4
1 T2    1.2        1          0        1        1          1        1       1          2        1

我已经大大简化了此功能。我的真实数据集比这个数据集(115组变量)大得多,实际上每个数字中都有许多不同的列。我只需要了解这个简单的示例即可上手。因此,想法是不调用每个名称就进行遍历。

1 个答案:

答案 0 :(得分:1)

如果将数据重整为“长”格式,则可以通过分组操作获得总和

library(tidyverse)

Answers <- 
  dat %>% 
    gather(key = 'NumNode', value = 'value', Number_2:node_age_4) %>% 
    group_by(grp = parse_number(NumNode)) %>% 
    do(Answer = with(.data, value[grep('Num', NumNode)] + value[grep('node', NumNode)]))

# # A tibble: 3 x 2
#     grp Answer
#   <dbl>  <dbl>
# 1  2.00   1.00
# 2  3.00   2.00
# 3  4.00   3.00

然后您可以通过if设置accumulate

来实现您的min逻辑
answers <- accumulate(Answers$Answer, pmin)
# [1] 1 1 1

您可以使用

将结果添加为dat的列

dat[paste0('Answer_', Answers$grp)] <- ifelse(is.list(answers), answers, as.list(answers))

具有> 1行的示例数据

dat <- data.frame(id = "T2", Height = 1.2, 
              Number_2 = 1:2, node_age_2 = 0:1, 
              Number_3 = 1:2, node_age_3 = 1:2, 
              Number_4 = 1:2, node_age_4 = 2:3)

上述方法的输出

  id Height Number_2 node_age_2 Number_3 node_age_3 Number_4 node_age_4 Answer_2 Answer_3 Answer_4
1 T2    1.2        1          0        1          1        1          2        1        1        1
2 T2    1.2        2          1        2          2        2          3        3        3        3