使每列的比率与每个列的

时间:2018-03-09 14:57:11

标签: r loops dataframe

这与calculate ratios for every 2 columns in a data frame

类似但不完全相同

我有一个数据框,我希望每个列与其他列的比例(在一个方向上是可以的,我不需要两个。)

df <- bind_cols(x = c(1, 2, 3), y = c(2, 3, 4), z = c(3, 4, 5))

ratios_df <- df %>% 
  mutate(x_y = x/y,
         x_z = x/z,
         y_z = y/z) %>% 
  select(-c(x:z))

如何制作更自动化的方法来生成ratios_df?

3 个答案:

答案 0 :(得分:2)

另一种方法是先使用combn创建组合,然后进行计算:

combos <- combn(names(df), 2, simplify = FALSE)

l2 <- lapply(combos, function(x) df[[ x[1] ]] / df[[ x[2] ]])

ratios_df <- setNames(as.data.frame(l2), sapply(l, paste, collapse = '_'))

给出:

> ratios_df
        x_y       x_z       y_z
1 0.5000000 0.3333333 0.6666667
2 0.6666667 0.5000000 0.7500000
3 0.7500000 0.6000000 0.8000000

答案 1 :(得分:2)

您可以使用combn将列组合在一起,然后将第一列与第二列分开:

combn(df, 2, function(x) x[[1]] / x[[2]])
          [,1]      [,2]      [,3]
[1,] 0.5000000 0.3333333 0.6666667
[2,] 0.6666667 0.5000000 0.7500000
[3,] 0.7500000 0.6000000 0.8000000

您也可以添加名称:

nam = combn(names(df),2,paste,collapse="_")
`colnames<-`(combn(df,2,function(x)x[[1]]/x[[2]]),nam)
           x_y       x_z       y_z
[1,] 0.5000000 0.3333333 0.6666667
[2,] 0.6666667 0.5000000 0.7500000
[3,] 0.7500000 0.6000000 0.8000000

答案 2 :(得分:1)

library(dplyr)

df <- bind_cols(x = c(1, 2, 3), y = c(2, 3, 4), z = c(3, 4, 5))

df_ratios <- as.data.frame(lapply(df, function(x) x/df))
df_ratios
# x.x       x.y       x.z      y.x y.y       y.z      z.x      z.y z.z
# 1   1 0.5000000 0.3333333 2.000000   1 0.6666667 3.000000 1.500000   1
# 2   1 0.6666667 0.5000000 1.500000   1 0.7500000 2.000000 1.333333   1
# 3   1 0.7500000 0.6000000 1.333333   1 0.8000000 1.666667 1.250000   1

df_ratios <- df_ratios[, sapply(strsplit(colnames(df_ratios), "\\."), function(x) x[1] > x[2])]
# y.x      z.x      z.y
# 1 2.000000 3.000000 1.500000
# 2 1.500000 2.000000 1.333333
# 3 1.333333 1.666667 1.250000