根据 R 中的其他变量值计算 select 变量的干净方法
Clean way to select variable for calculations depending on other variable value in R
我正在使用具有以下结构的数据框:
ID origin value1 value2
1 A 100 50
1 A 200 100
2 B 10 2
2 B 150 30
所以每一行可以有不同的来源,我需要通过 ID 进行一些计算,但我使用的值变量取决于来源变量。因此,如果 origin == 'A'
我应该使用 value1
,如果是 B 我应该使用 value2
。在不考虑最后一个条件的情况下,我的代码如下所示:
df2 <- df %>%
group_by(ID) %>%
mutate(mean_value = mean(value1, na.rm = TRUE),
sd_value = sd(value1, na.rm = TRUE),
median_value = median(value1, na.rm = TRUE),
cv_value = sd_value1/mean_value1,
p25_value = quantile(value1, 0.25, na.rm = TRUE),
p75_value = quantile(value1, 0.75, na.rm = TRUE))
我知道我可以在每一行添加一个 if_else
语句,但我认为我的代码会失去一些可读性(在我的实际数据中有多个来源,这使得这有点麻烦)。所以,我正在考虑创建一个自定义函数,可能使用 map
或者可能使用 group_by origin 的东西,但我没有找到实现这些选项的好方法。有任何想法吗?我想要的数据框看起来像这样(为简单起见,我将只添加第一个 mutate 列):
ID origin value1 value2 mean_value
1 A 100 50 150
1 A 200 100 150
2 B 10 2 16
2 B 150 30 16
所以第一个平均值是 (100 + 200) / 2
(来自值 1),第二个是 (30 + 2) / 2
(来自值 2)。
谢谢!
我们可以先创建一个临时列,然后再执行 mean
。这样,我们可能只需要使用一次ifelse/case_when
library(dplyr)
df %>%
mutate(valuenew = case_when(origin == 'A' ~ value1,
TRUE ~ value2)) %>%
group_by(ID) %>%
mutate(mean_value = mean(valuenew, na.rm = TRUE), .keep = "unused") %>%
ungroup
-输出
# A tibble: 4 × 5
ID origin value1 value2 mean_value
<int> <chr> <int> <int> <dbl>
1 1 A 100 50 150
2 1 A 200 100 150
3 2 B 10 2 16
4 2 B 150 30 16
数据
df <- structure(list(ID = c(1L, 1L, 2L, 2L), origin = c("A", "A", "B",
"B"), value1 = c(100L, 200L, 10L, 150L), value2 = c(50L, 100L,
2L, 30L)), class = "data.frame", row.names = c(NA, -4L))
我正在使用具有以下结构的数据框:
ID origin value1 value2
1 A 100 50
1 A 200 100
2 B 10 2
2 B 150 30
所以每一行可以有不同的来源,我需要通过 ID 进行一些计算,但我使用的值变量取决于来源变量。因此,如果 origin == 'A'
我应该使用 value1
,如果是 B 我应该使用 value2
。在不考虑最后一个条件的情况下,我的代码如下所示:
df2 <- df %>%
group_by(ID) %>%
mutate(mean_value = mean(value1, na.rm = TRUE),
sd_value = sd(value1, na.rm = TRUE),
median_value = median(value1, na.rm = TRUE),
cv_value = sd_value1/mean_value1,
p25_value = quantile(value1, 0.25, na.rm = TRUE),
p75_value = quantile(value1, 0.75, na.rm = TRUE))
我知道我可以在每一行添加一个 if_else
语句,但我认为我的代码会失去一些可读性(在我的实际数据中有多个来源,这使得这有点麻烦)。所以,我正在考虑创建一个自定义函数,可能使用 map
或者可能使用 group_by origin 的东西,但我没有找到实现这些选项的好方法。有任何想法吗?我想要的数据框看起来像这样(为简单起见,我将只添加第一个 mutate 列):
ID origin value1 value2 mean_value
1 A 100 50 150
1 A 200 100 150
2 B 10 2 16
2 B 150 30 16
所以第一个平均值是 (100 + 200) / 2
(来自值 1),第二个是 (30 + 2) / 2
(来自值 2)。
谢谢!
我们可以先创建一个临时列,然后再执行 mean
。这样,我们可能只需要使用一次ifelse/case_when
library(dplyr)
df %>%
mutate(valuenew = case_when(origin == 'A' ~ value1,
TRUE ~ value2)) %>%
group_by(ID) %>%
mutate(mean_value = mean(valuenew, na.rm = TRUE), .keep = "unused") %>%
ungroup
-输出
# A tibble: 4 × 5
ID origin value1 value2 mean_value
<int> <chr> <int> <int> <dbl>
1 1 A 100 50 150
2 1 A 200 100 150
3 2 B 10 2 16
4 2 B 150 30 16
数据
df <- structure(list(ID = c(1L, 1L, 2L, 2L), origin = c("A", "A", "B",
"B"), value1 = c(100L, 200L, 10L, 150L), value2 = c(50L, 100L,
2L, 30L)), class = "data.frame", row.names = c(NA, -4L))