英文:
How can I subtract values of each column of my dataframe from all other columns?
问题
Here is the translated code portion:
我有一个简单的数据框
df <- data.frame(
col1 = c(1, 2, 3),
col2 = c(4, 5, 6),
col3 = c(7, 8, 9)
)
我想要一个新的数据框,其中包含每一列与其他列的减法结果,依次计算。我认为这会完成任务
result_df <- data.frame()
# 从所有其他列中减去每一列
for (i in 1:ncol(df)) {
column_diff <- apply(df[, -i], 2, function(x) df[, i] - x)
result_df <- cbind(result_df, column_diff)
}
但问题是什么?
英文:
I have a simple datafrme
df <- data.frame(
col1 = c(1, 2, 3),
col2 = c(4, 5, 6),
col3 = c(7, 8, 9)
)
And I want to have a new dataframe that will contain the results of subtraction of each column from all others, one by one. I assume that will do the job
result_df <- data.frame()
# Subtract each column from all the other columns
for (i in 1:ncol(df)) {
column_diff <- apply(df[, -i], 2, function(x) df[, i] - x)
result_df <- cbind(result_df, column_diff)
}
but what is the issue?
答案1
得分: 1
如果您想要使用 cbind()
,您需要将具有相同列数的元素组合在一起。我认为您可以像这样设置 result_df
:
result_df <- data.frame(matrix(nrow=3, ncol=0))
或者创建一个列差异的列表,然后将它们组合起来可能更好:
cdiff <- function(i) apply(df[, -i], 2, function(x) df[, i] - x)
newcols <- lapply(1:ncol(df), cdiff)
data.frame(newcols)
英文:
If you want to cbind()
you need to combine elements with the same number of columns. I think you could set up result_df
like this:
result_df <- data.frame(matrix(nrow=3, ncol = 0))
Or it might be better to create a list of column-differences, then combine them:
cdiff <- function(i) apply(df[, -i], 2, function(x) df[, i] - x)
newcols <- lapply(1:ncol(df), cdiff)
data.frame(newcols)
答案2
得分: 1
简单
在 {tidyverse} 中,可以使用 purrr::map_dfc()
来执行类似于您所使用的函数:
library(tidyverse)
d <- data.frame(col1 = 1:3, col2 = 4:6, col3 = 7:9)
seq_along(d) %>% map_dfc(.f = \(x){d[,x] - d[,-x]})
#> col2...1 col3...2 col1...3 col3...4 col1...5 col2...6
#> 1 -3 -6 3 -3 6 3
#> 2 -3 -6 3 -3 6 3
#> 3 -3 -6 3 -3 6 3
创建于 2023-06-04,使用 reprex v2.0.2
更新
purrr::map_dfc()
在 {purrr} 1.0.0 中已弃用,现在可以使用 map()
与 list_cbind()
来进行正确的操作,这允许您指定 names_repair
参数以控制命名。
seq_along(d) %>%
map(.f = \(x){d[,x] - d[,-x]}) %>%
list_cbind(name_repair = "minimal")
#> col2 col3 col1 col3 col1 col2
#> 1 -3 -6 3 -3 6 3
#> 2 -3 -6 3 -3 6 3
#> 3 -3 -6 3 -3 6 3
创建于 2023-06-05,使用 reprex v2.0.2
高级
如果您想要更高级的操作,并且希望新列反映生成它们的计算过程,您可以使用 dplyr::rename_with()
。
seq_along(d) %>%
map(.f = \(x) {
d[, x] - d[,-x] %>%
rename_with(\(y) {paste0(names(d)[x], "-", y)})
}) %>%
list_cbind()
#> col1-col2 col1-col3 col2-col1 col2-col3 col3-col1 col3-col2
#> 1 -3 -6 3 -3 6 3
#> 2 -3 -6 3 -3 6 3
#> 3 -3 -6 3 -3 6 3
创建于 2023-06-05,使用 reprex v2.0.2
英文:
Simple
In the {tidyverse} this can be done with purrr::map_dfc()
using a function similar to what you had:
library(tidyverse)
d <- data.frame(col1 = 1:3, col2 = 4:6, col3 = 7:9)
seq_along(d) %>% map_dfc(.f = \(x){d[,x] - d[,-x]})
#> col2...1 col3...2 col1...3 col3...4 col1...5 col2...6
#> 1 -3 -6 3 -3 6 3
#> 2 -3 -6 3 -3 6 3
#> 3 -3 -6 3 -3 6 3
<sup>Created on 2023-06-04 with reprex v2.0.2</sup>
Updated
purrr::map_dfc()
was deprecated in {purrr} 1.0.0 so it would properly be done now using map()
with list_cbind()
which enables one to specify the names_repair
argument to control the naming.
seq_along(d) %>%
map(.f = \(x){d[,x] - d[,-x]}) %>%
list_cbind(name_repair = "minimal")
#> col2 col3 col1 col3 col1 col2
#> 1 -3 -6 3 -3 6 3
#> 2 -3 -6 3 -3 6 3
#> 3 -3 -6 3 -3 6 3
<sup>Created on 2023-06-05 with reprex v2.0.2</sup>
Fancy
If you you want to get fancy and have the new columns reflect the calculation that produced them, you could use dplyr::rename_with()
.
seq_along(d) %>%
map(.f = \(x) {
d[, x] - d[,-x] %>%
rename_with(\(y) {paste0(names(d)[x], "-", y)})
}) %>%
list_cbind()
#> col1-col2 col1-col3 col2-col1 col2-col3 col3-col1 col3-col2
#> 1 -3 -6 3 -3 6 3
#> 2 -3 -6 3 -3 6 3
#> 3 -3 -6 3 -3 6 3
<sup>Created on 2023-06-05 with reprex v2.0.2</sup>
答案3
得分: 0
以下是您要翻译的内容:
"While I prefer the solution by @Ben Bolker, here is a fun one:
library(dplyr)
library(purrr)
cdiff <- function(x) {
df %>%
select(-{{x}}) %>%
transmute(!!paste0("col", x, ".diff") := df[[x]] - .)
}
map_dfc(1:ncol(df), cdiff)
col1.diff.col2 col1.diff.col3 col2.diff.col1 col2.diff.col3 col3.diff.col1 col3.diff.col2
1 -3 -6 3 -3 6 3
2 -3 -6 3 -3 6 3
3 -3 -6 3 -3 6 3
```"
<details>
<summary>英文:</summary>
While I prefer the solution by @Ben Bolker, here is a fun one:
library(dplyr)
library(purrr)
cdiff <- function(x) {
df %>%
select(-{{x}}) %>%
transmute(!!paste0("col", x, ".diff") := df[[x]] - .)
}
map_dfc(1:ncol(df), cdiff)
col1.diff.col2 col1.diff.col3 col2.diff.col1 col2.diff.col3 col3.diff.col1 col3.diff.col2
1 -3 -6 3 -3 6 3
2 -3 -6 3 -3 6 3
3 -3 -6 3 -3 6 3
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论