有没有办法使用mutate遍历列名?

时间:2019-06-10 14:42:14

标签: r dplyr

我有一个数据框,它描述了一个o个体在x-y平面上的25个点。对于三个看起来像这样的人:

input_data

   id  x1  y1  x2  y2  x3  y3 ... x25  y25  
   1   9   3   4   7   1   3  ... 2    8     
   2   2   5   3   3   1   7  ... 9    6
   3   5   4   1   8   9   4  ... 2    7

我想计算一个称为TMI的复杂数字,该数字是为x-y对之间的每次比较定义的。例如,对于点(x1,y1)和(x2,y2),TMI为:

input_data <- input_data %>% 
    mutate(
      A = (x1/x2) + (y1/y2),
      TMI_1_2 = case_when(
      x1 == x2 & y1 == y2 ~ (1-sqrt(pmin((x1*y2)/(x2*y1),(x1*y2)/(x2*y1)))),
      x2/x1 + y2/y1 >= 1 & A == 1 ~ 0,
      TRUE ~ 1)
  )

现在,我必须为25个x-y组合的所有可能对(即300对)计算该数字。以下内容很清楚:

list_points <- seq.int(25)
table_comparisons <- combn(list_points, 2)

使用mutate遍历列名的最佳方法是什么,这样我可以计算出所需的300个不同的TMI?

我虽然可以执行以下操作,但不能:

for(i in 1:300) { 
  point1 <- table_comparisons[1,i]
  point2 <- table_comparisons[2,i]

input_data <- input_data %>% 
    mutate(
      A = (xpoint1/xpoint2) + (ypoint1/ypoint2),
      TMI_point1_point2 = case_when(
      xpoint1 == xpoint2 & ypoint1 == ypoint2 ~ (1-sqrt(pmin((xpoint1*ypoint2)/(xpoint2*ypoint1),(xpoint1*ypoint2)/(xpoint2*ypoint1)))),
      xpoint2/xpoint1 + ypoint2/ypoint1 >= 1 & A == 1 ~ 0,
      TRUE ~ 1)
  )
}

有什么想法吗?

感谢您的时间!

1 个答案:

答案 0 :(得分:0)

在应用公式之前,最好将数据转换为x,y对。试试这个:

library(tidyverse)

input_data <- tibble(ID = seq(1:5),
                     x1 = runif(5),
                     y1 = runif(5),
                     x2 = runif(5),
                     y2 = runif(5)
                     )

input_data_long <- input_data %>% 
  gather(key, value, -ID) %>% 
  mutate(key1 = stringr::str_extract(key, "[a-zA-Z]"),
         key2 = stringr::str_extract(key, "\\d+")) %>% 
  select(-key) %>% 
  spread(key1, value)

现在,您可以从x&y中更改一个新列,然后将表散布为所需的任何格式。