如何使用维度而不是列名跨数据框进行突变?

How to mutate across a dataframe using dimensions instead of column names?

下面的代码很好地计算和输出了名为 data:

的数据框中每个元素所代表的行总数的比例

输出:

# A tibble: 4 x 5
# Rowwise: 
  To        A     B     C   Sum
  <chr> <dbl> <dbl> <dbl> <dbl>
1 A     0.111 0.333 0.556     1
2 B     0.167 0.333 0.5       1
3 C     0.25  0.312 0.438     1
4 Sum   0.189 0.324 0.486     1

生成以上代码:

library(dplyr)
library(tidyverse)

data <- 
  data.frame(
    To = c("A","B","C"),
    A = c(1,2,4),
    B = c(3,4,5),
    C = c(5,6,7)
  )

data <- data %>% 
  replace(is.na(.), 0) %>%
  bind_rows(summarise_all(., ~(if(is.numeric(.)) sum(.) else "Sum")))

data <- cbind(data, Sum = rowSums(data[,-1]))

data %>% 
  rowwise() %>%
  mutate(across(A:Sum, ~ sum(.) / Sum))

上面的mutate(across(...)...)引用起始列A作为计算起点,是正确的。但是,在更大的应用程序中,列名称是动态的。所以我只想从数据框中的第一个数字列开始,而不是使用它的名称。以下是我的尝试:

data %>% 
  rowwise() %>%
  mutate(across(-1:Sum, ~ sum(.) / Sum))

它计算正确但给我如下所示的警告。有一个更好的方法吗?而不是 suppressWarnings() 哪个更诱人?

警告信息: mutate() 输入 ..1 有问题。 我 ..1 = across(-1:Sum, ~sum(.)/Sum)。 i 数值表达式有 4 个元素:只有第一个被使用 i 警告发生在第 1 行。

您可以使用谓词函数,包裹在 where()

data %>% 
  rowwise() %>%
  mutate(across(where(is.numeric), ~ sum(.) / Sum))

您也可以只 de-select 第一列及其名称或索引,如下例所示:

data %>% 
  rowwise() %>%
  mutate(across(-1, ~ sum(.) / Sum))

data %>% 
  rowwise() %>%
  mutate(across(-To, ~ sum(.) / Sum))