如何使用动态维度引用跨数据框进行变异?
How to mutate across a dataframe using dynamic dimension references?
假设我们从下面显示的 data
数据帧开始,生成代码就在下面:
> data
To A B C
1 A 1 3 5
2 B 2 4 6
3 C 4 5 7
4 Sum 7 12 18
library(dplyr)
data <-
data.frame(
To = c("A","B","C"),
A = c(1,2,4),
B = c(3,4,5),
C = c(5,6,7)
) %>%
bind_rows(summarise_all(., ~(if(is.numeric(.)) sum(.) else "Sum")))
我已经 运行 下面的代码将数据框中的值更改为百分比(每个单元格计算为其各自列“总和”的百分比):
data %>% mutate(across(-1, ~ ./.[To == "Sum"]))
给出正确的输出:
> data
To A B C
1 A 0.1428571 0.2500000 0.2777778
2 B 0.2857143 0.3333333 0.3333333
3 C 0.5714286 0.4166667 0.3888889
4 Sum 1.0000000 1.0000000 1.0000000
如何将 mutate(across...))
中 [To == "Sum"]
的除数与对数据帧最后一行的动态(可能是数字)引用交换?在更完整的代码中,它根据用户对 Shiny 的输入动态地和反应性地 expands/contracts 部署在数据框中,并且列 header 名称也会动态更改,因此对“To”的固定引用 header此示例中的名称不是最佳名称。
简单的解释一下也有帮助,这样我就不用一直跑到槽里找答案了。
我们可以使用last
函数来return 列的最后一个值。此外,nth
还有另一个选项,我们可以根据更通用的索引获取列的值,即 nth(., 2)
return 是第二个值
library(dplyr)
data %>%
mutate(across(-1, ~ ./last(.)))
-输出
To A B C
1 A 0.1428571 0.2500000 0.2777778
2 B 0.2857143 0.3333333 0.3333333
3 C 0.5714286 0.4166667 0.3888889
4 Sum 1.0000000 1.0000000 1.0000000
在 Base R 中你可以这样做:
addmargins(prop.table(as.matrix(data.frame(data, row.names = 1)),2),1)
A B C
A 0.1428571 0.2500000 0.2777778
B 0.2857143 0.3333333 0.3333333
C 0.5714286 0.4166667 0.3888889
Sum 1.0000000 1.0000000 1.0000000
试试这个:这或多或少是 akrun 已经呈现的:
library(dplyr)
data <-
data.frame(
To = c("A","B","C"),
A = c(1,2,4),
B = c(3,4,5),
C = c(5,6,7)
) %>%
mutate(across(-1, ~ ./sum(.))) %>%
bind_rows(summarise_all(., ~(if(is.numeric(.)) sum(.) else "Sum")))
To A B C
1 A 0.1428571 0.2500000 0.2777778
2 B 0.2857143 0.3333333 0.3333333
3 C 0.5714286 0.4166667 0.3888889
4 Sum 1.0000000 1.0000000 1.0000000
假设我们从下面显示的 data
数据帧开始,生成代码就在下面:
> data
To A B C
1 A 1 3 5
2 B 2 4 6
3 C 4 5 7
4 Sum 7 12 18
library(dplyr)
data <-
data.frame(
To = c("A","B","C"),
A = c(1,2,4),
B = c(3,4,5),
C = c(5,6,7)
) %>%
bind_rows(summarise_all(., ~(if(is.numeric(.)) sum(.) else "Sum")))
我已经 运行 下面的代码将数据框中的值更改为百分比(每个单元格计算为其各自列“总和”的百分比):
data %>% mutate(across(-1, ~ ./.[To == "Sum"]))
给出正确的输出:
> data
To A B C
1 A 0.1428571 0.2500000 0.2777778
2 B 0.2857143 0.3333333 0.3333333
3 C 0.5714286 0.4166667 0.3888889
4 Sum 1.0000000 1.0000000 1.0000000
如何将 mutate(across...))
中 [To == "Sum"]
的除数与对数据帧最后一行的动态(可能是数字)引用交换?在更完整的代码中,它根据用户对 Shiny 的输入动态地和反应性地 expands/contracts 部署在数据框中,并且列 header 名称也会动态更改,因此对“To”的固定引用 header此示例中的名称不是最佳名称。
简单的解释一下也有帮助,这样我就不用一直跑到槽里找答案了。
我们可以使用last
函数来return 列的最后一个值。此外,nth
还有另一个选项,我们可以根据更通用的索引获取列的值,即 nth(., 2)
return 是第二个值
library(dplyr)
data %>%
mutate(across(-1, ~ ./last(.)))
-输出
To A B C
1 A 0.1428571 0.2500000 0.2777778
2 B 0.2857143 0.3333333 0.3333333
3 C 0.5714286 0.4166667 0.3888889
4 Sum 1.0000000 1.0000000 1.0000000
在 Base R 中你可以这样做:
addmargins(prop.table(as.matrix(data.frame(data, row.names = 1)),2),1)
A B C
A 0.1428571 0.2500000 0.2777778
B 0.2857143 0.3333333 0.3333333
C 0.5714286 0.4166667 0.3888889
Sum 1.0000000 1.0000000 1.0000000
试试这个:这或多或少是 akrun 已经呈现的:
library(dplyr)
data <-
data.frame(
To = c("A","B","C"),
A = c(1,2,4),
B = c(3,4,5),
C = c(5,6,7)
) %>%
mutate(across(-1, ~ ./sum(.))) %>%
bind_rows(summarise_all(., ~(if(is.numeric(.)) sum(.) else "Sum")))
To A B C
1 A 0.1428571 0.2500000 0.2777778
2 B 0.2857143 0.3333333 0.3333333
3 C 0.5714286 0.4166667 0.3888889
4 Sum 1.0000000 1.0000000 1.0000000