dplyr 使用条件列和特定行进行变异
dplyr mutate using conditional column and specific rows
我有一个包含两个得分列的 data.frame。我想在每行的基础上有条件地使用其中之一的数据。我用下面的例子解释...
> dff <- data.frame(dataset = c('Main','Main','b','b','c','c','d','d'),
+ score1 = c(0.01,0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08),
+ score2 = c(0.001, 0.2, 0.003, 0.4, 0.005, 0.6, 0.007, 0.8),
+ name = c('A','B','A','B','A','B','A','B'));
> dff
dataset score1 score2 name
1 Main 0.01 0.001 A
2 Main 0.02 0.200 B
3 b 0.03 0.003 A
4 b 0.04 0.400 B
5 c 0.05 0.005 A
6 c 0.06 0.600 B
7 d 0.07 0.007 A
8 d 0.08 0.800 B
我正在尝试 select 对 name == 'A'
的所有行的一个分数的所有值,对于 name == 'B'
也是类似的。我选择哪个分数取决于dataset == 'Main'
时哪个分数较小。
因此,例如,在此示例中,当 name == 'A'
时,score2
低于 Main
数据集的 score1
。因此,对于 name == 'A'
所在的所有行,我将使用它们在 score2
.
中的值
当 name == 'B'
时,score1
低于 Main
数据集的 score2
。因此,对于 name == 'B'
所在的所有行,我将使用它们在 score1
中的值。最终结果如下所示:
dataset score1 score2 name final
1 Main 0.01 0.001 A 0.001
2 Main 0.02 0.200 B 0.020
3 b 0.03 0.003 A 0.003
4 b 0.04 0.400 B 0.040
5 c 0.05 0.005 A 0.005
6 c 0.06 0.600 B 0.060
7 d 0.07 0.007 A 0.007
8 d 0.08 0.800 B 0.080
所以我想做的是有条件地改变并创建新的 final
列,这取决于该行的名称以及 Main
数据集的哪个列较小同一个名字。我正在尝试想出一些优雅的方法来实现这一点,而不是一堆奇怪的代码行,但我还没有能够做到这一点。
编辑:
我在这里包含了我的实际数据样本。
structure(list(datasets = c("main", "main", "bms", "bms", "sny",
"sny", "chen", "chen", "van", "van"), test_high = c(0.639654382299527,
0.561881930194033, NA, NA, 0.909598942079794, 0.651429614317738,
0.189274551669056, 0.541845226349475, 0.41969855766237, 0.555858598773613
), test_low = c(0.402779917451124, 0.469868712458501, NA, NA,
0.106383376175001, 0.381060050671353, 0.824427629626441, 0.468590829264603,
0.594646024750062, 0.460036802365713), cell = c("high", "low",
"low", "high", "high", "low", "high", "low", "low", "high")), .Names = c("datasets",
"test_high", "test_low", "cell"), class = c("tbl_df", "tbl",
"data.frame"), row.names = c(NA, -10L))
# A tibble: 10 x 4
datasets test_high test_low cell
<chr> <dbl> <dbl> <chr>
1 main 0.6396544 0.4027799 high
2 main 0.5618819 0.4698687 low
3 bms NA NA low
4 bms NA NA high
5 sny 0.9095989 0.1063834 high
6 sny 0.6514296 0.3810601 low
7 chen 0.1892746 0.8244276 high
8 chen 0.5418452 0.4685908 low
9 van 0.4196986 0.5946460 low
10 van 0.5558586 0.4600368 high
Final 在这种情况下最终会与 test_low 相同,因为对于两个主电源(即当电池为 'high' 和电池为 'low' 时)test_low 列小于 test_high 列。
一个选项是case_when
library(dplyr)
dff %>%
mutate(final = case_when(name == "A" & dataset == "Main" ~ score2,
name == "B" & dataset=="Main" ~score1,
TRUE ~ pmin(score1, score2)))
# dataset score1 score2 name final
#1 Main 0.01 0.001 A 0.001
#2 Main 0.02 0.200 B 0.020
#3 b 0.03 0.003 A 0.003
#4 b 0.04 0.400 B 0.040
#5 c 0.05 0.005 A 0.005
#6 c 0.06 0.600 B 0.060
#7 d 0.07 0.007 A 0.007
#8 d 0.08 0.800 B 0.080
基于编辑后的数据集('dfn'),
dfn %>%
filter(datasets == "main") %>%
gather(test, val, test_high:test_low) %>%
group_by(cell) %>%
summarise(test = test[which.max(val)]) %>%
left_join(dfn, .) %>%
rowwise() %>%
mutate(final = get(test)) %>%
select(-test)
dff$final <- ifelse(dff$score2 < dff$score1 & dff$dataset == 'Main', dff$score2, dff$score1)
我有一个包含两个得分列的 data.frame。我想在每行的基础上有条件地使用其中之一的数据。我用下面的例子解释...
> dff <- data.frame(dataset = c('Main','Main','b','b','c','c','d','d'),
+ score1 = c(0.01,0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08),
+ score2 = c(0.001, 0.2, 0.003, 0.4, 0.005, 0.6, 0.007, 0.8),
+ name = c('A','B','A','B','A','B','A','B'));
> dff
dataset score1 score2 name
1 Main 0.01 0.001 A
2 Main 0.02 0.200 B
3 b 0.03 0.003 A
4 b 0.04 0.400 B
5 c 0.05 0.005 A
6 c 0.06 0.600 B
7 d 0.07 0.007 A
8 d 0.08 0.800 B
我正在尝试 select 对 name == 'A'
的所有行的一个分数的所有值,对于 name == 'B'
也是类似的。我选择哪个分数取决于dataset == 'Main'
时哪个分数较小。
因此,例如,在此示例中,当 name == 'A'
时,score2
低于 Main
数据集的 score1
。因此,对于 name == 'A'
所在的所有行,我将使用它们在 score2
.
当 name == 'B'
时,score1
低于 Main
数据集的 score2
。因此,对于 name == 'B'
所在的所有行,我将使用它们在 score1
中的值。最终结果如下所示:
dataset score1 score2 name final
1 Main 0.01 0.001 A 0.001
2 Main 0.02 0.200 B 0.020
3 b 0.03 0.003 A 0.003
4 b 0.04 0.400 B 0.040
5 c 0.05 0.005 A 0.005
6 c 0.06 0.600 B 0.060
7 d 0.07 0.007 A 0.007
8 d 0.08 0.800 B 0.080
所以我想做的是有条件地改变并创建新的 final
列,这取决于该行的名称以及 Main
数据集的哪个列较小同一个名字。我正在尝试想出一些优雅的方法来实现这一点,而不是一堆奇怪的代码行,但我还没有能够做到这一点。
编辑: 我在这里包含了我的实际数据样本。
structure(list(datasets = c("main", "main", "bms", "bms", "sny",
"sny", "chen", "chen", "van", "van"), test_high = c(0.639654382299527,
0.561881930194033, NA, NA, 0.909598942079794, 0.651429614317738,
0.189274551669056, 0.541845226349475, 0.41969855766237, 0.555858598773613
), test_low = c(0.402779917451124, 0.469868712458501, NA, NA,
0.106383376175001, 0.381060050671353, 0.824427629626441, 0.468590829264603,
0.594646024750062, 0.460036802365713), cell = c("high", "low",
"low", "high", "high", "low", "high", "low", "low", "high")), .Names = c("datasets",
"test_high", "test_low", "cell"), class = c("tbl_df", "tbl",
"data.frame"), row.names = c(NA, -10L))
# A tibble: 10 x 4
datasets test_high test_low cell
<chr> <dbl> <dbl> <chr>
1 main 0.6396544 0.4027799 high
2 main 0.5618819 0.4698687 low
3 bms NA NA low
4 bms NA NA high
5 sny 0.9095989 0.1063834 high
6 sny 0.6514296 0.3810601 low
7 chen 0.1892746 0.8244276 high
8 chen 0.5418452 0.4685908 low
9 van 0.4196986 0.5946460 low
10 van 0.5558586 0.4600368 high
Final 在这种情况下最终会与 test_low 相同,因为对于两个主电源(即当电池为 'high' 和电池为 'low' 时)test_low 列小于 test_high 列。
一个选项是case_when
library(dplyr)
dff %>%
mutate(final = case_when(name == "A" & dataset == "Main" ~ score2,
name == "B" & dataset=="Main" ~score1,
TRUE ~ pmin(score1, score2)))
# dataset score1 score2 name final
#1 Main 0.01 0.001 A 0.001
#2 Main 0.02 0.200 B 0.020
#3 b 0.03 0.003 A 0.003
#4 b 0.04 0.400 B 0.040
#5 c 0.05 0.005 A 0.005
#6 c 0.06 0.600 B 0.060
#7 d 0.07 0.007 A 0.007
#8 d 0.08 0.800 B 0.080
基于编辑后的数据集('dfn'),
dfn %>%
filter(datasets == "main") %>%
gather(test, val, test_high:test_low) %>%
group_by(cell) %>%
summarise(test = test[which.max(val)]) %>%
left_join(dfn, .) %>%
rowwise() %>%
mutate(final = get(test)) %>%
select(-test)
dff$final <- ifelse(dff$score2 < dff$score1 & dff$dataset == 'Main', dff$score2, dff$score1)