如何使用tidyverse中的相邻列修改另一列中命名的列?
How to modify a column named in another column using adjacent column in tidyverse?
我有以下数据框,
df <- tibble(x = c(2, 3, 4)) %>%
mutate(`1` = 99, `2` = 88, `3` = 77, `4` = 66, `5` = 55)
列 x
包含需要操作的列名,该列中的值必须替换为列 x-1
、x
和 x+1
。例如,对于 x
为 2 的第一行,列 2
中的值必须替换为 (99+88+77) = 264.
我尝试使用双大括号 ({{}}
) 和 :=
,如下所示,
df %>%
mutate("{{x}}" := {{x-1}} + {{x}} + {{x+1}})
但我收到以下错误,
Error in local_error_context(dots = dots, .index = i, mask = mask) : promise already under evaluation: recursive default argument reference or earlier problems?
然后我尝试使用 across()
内的 cur_column()
访问该列,如下所示,
df %>%
mutate(across(-x, ~if_else(x == cur_column(), {{cur_column()}}, .x)))
我遇到了与上述相同的错误,我想我可能错误地使用了 curly 运算符,有人可以帮忙吗?
{{}}
语法适用于将未计算的表达式传递给 dplyr 命令时,它不适用于捕获列值。
大多数情况下,在每一行的不同列上执行不同的选项并不容易。一种替代方法是重塑数据,以便您可以使用 lead/lag 函数。然后你就可以回头了。
library(dplyr)
library(tidyr)
df %>%
mutate(row = row_number()) %>%
pivot_longer(!c(x, row)) %>%
mutate(name = as.integer(name)) %>%
group_by(row) %>%
mutate(value=if_else(x==name, value + lead(value) + lag(value), value)) %>%
pivot_wider(c(row, x)) %>%
select(-row)
# row x `1` `2` `3` `4` `5`
# <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 2 99 264 77 66 55
# 2 2 3 99 88 231 66 55
# 3 3 4 99 88 77 198 55
另一种方法是创建一个可以使用 rowwise()
访问 cur_column()
和 cur_data()
的辅助函数,以便为每一行创建不同的转换。
colclump <- function(target) {
prevc <- as.character(as.integer(target)-1)
nextc <- as.character(as.integer(target)+1)
function(x) {
if (cur_column()==target) {
x + cur_data()[[prevc]] + cur_data()[[nextc]]
} else {
x
}
}
}
df %>%
rowwise() %>%
mutate(across(-x, ~colclump(x)(.x)))
也许这个也符合你的目的:
for(k in 2:4) {
df[k-1,k+1] <- df[k-1,as.character(df$x[k-1])] +
df[k-1,as.character(df$x[k-1]-1)] +
df[k-1,as.character(df$x[k-1]+1)]
}
df
# A tibble: 3 x 6
# x `1` `2` `3` `4` `5`
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 2 99 264 77 66 55
# 2 3 99 88 231 66 55
# 3 4 99 88 77 198 55
我有以下数据框,
df <- tibble(x = c(2, 3, 4)) %>%
mutate(`1` = 99, `2` = 88, `3` = 77, `4` = 66, `5` = 55)
列 x
包含需要操作的列名,该列中的值必须替换为列 x-1
、x
和 x+1
。例如,对于 x
为 2 的第一行,列 2
中的值必须替换为 (99+88+77) = 264.
我尝试使用双大括号 ({{}}
) 和 :=
,如下所示,
df %>%
mutate("{{x}}" := {{x-1}} + {{x}} + {{x+1}})
但我收到以下错误,
Error in local_error_context(dots = dots, .index = i, mask = mask) : promise already under evaluation: recursive default argument reference or earlier problems?
然后我尝试使用 across()
内的 cur_column()
访问该列,如下所示,
df %>%
mutate(across(-x, ~if_else(x == cur_column(), {{cur_column()}}, .x)))
我遇到了与上述相同的错误,我想我可能错误地使用了 curly 运算符,有人可以帮忙吗?
{{}}
语法适用于将未计算的表达式传递给 dplyr 命令时,它不适用于捕获列值。
大多数情况下,在每一行的不同列上执行不同的选项并不容易。一种替代方法是重塑数据,以便您可以使用 lead/lag 函数。然后你就可以回头了。
library(dplyr)
library(tidyr)
df %>%
mutate(row = row_number()) %>%
pivot_longer(!c(x, row)) %>%
mutate(name = as.integer(name)) %>%
group_by(row) %>%
mutate(value=if_else(x==name, value + lead(value) + lag(value), value)) %>%
pivot_wider(c(row, x)) %>%
select(-row)
# row x `1` `2` `3` `4` `5`
# <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 2 99 264 77 66 55
# 2 2 3 99 88 231 66 55
# 3 3 4 99 88 77 198 55
另一种方法是创建一个可以使用 rowwise()
访问 cur_column()
和 cur_data()
的辅助函数,以便为每一行创建不同的转换。
colclump <- function(target) {
prevc <- as.character(as.integer(target)-1)
nextc <- as.character(as.integer(target)+1)
function(x) {
if (cur_column()==target) {
x + cur_data()[[prevc]] + cur_data()[[nextc]]
} else {
x
}
}
}
df %>%
rowwise() %>%
mutate(across(-x, ~colclump(x)(.x)))
也许这个也符合你的目的:
for(k in 2:4) {
df[k-1,k+1] <- df[k-1,as.character(df$x[k-1])] +
df[k-1,as.character(df$x[k-1]-1)] +
df[k-1,as.character(df$x[k-1]+1)]
}
df
# A tibble: 3 x 6
# x `1` `2` `3` `4` `5`
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 2 99 264 77 66 55
# 2 3 99 88 231 66 55
# 3 4 99 88 77 198 55