我想使用相同的广义one
创建三个新变量(分别称为two
,three
和mutate
),但内部使用不同的现有变量mutate
。为此,我想编写一个简短的代码块来完成与以下(详细)代码相同的事情:
mtcars.modified <- mtcars %>%
mutate(one = factor(case_when(
mpg < 10 ~ "lt10",
mpg >= 10 & mpg <= 20 ~ "10to20",
mpg > 20 ~ "gt20"),
ordered=T, levels = c("lt10", "10to20", "gt20"))) %>%
mutate(two = factor(case_when(
disp < 10 ~ "lt10",
disp >= 10 & disp <= 20 ~ "10to20",
disp > 20 ~ "gt20"),
ordered=T, levels = c("lt10", "10to20", "gt20"))) %>%
mutate(three = factor(case_when(
qsec < 10 ~ "lt10",
qsec >= 10 & qsec <= 20 ~ "10to20",
qsec > 20 ~ "gt20"),
ordered =T, levels = c("lt10", "10to20", "gt20")))
我可以概括这种情况的一种方法是使用mutate_at
的后缀行为,然后再重命名:
mtcars.modified <- mtcars %>%
mutate_at(c("mpg", "disp", "qsec"),
funs(mod = factor(case_when(
. < 10 ~ "lt10",
. >= 10 & . <= 20 ~ "10to20",
. > 20 ~ "gt20"),
ordered =T, levels = c("lt10", "10to20", "gt20")))) %>%
rename(one = mpg_mod,
two = disp_mod,
three = qsec_mod)
不过,这似乎是一种解决方法。有什么方法可以执行此操作而无需事后rename
吗?我想知道是否可以给one
,two
和three
作为.vars
,然后以某种方式将第二组变量传递到case_when
中。感觉类似于一个map2
问题,在该问题中,您有两个对应的向量,以及一个函数,该函数成对地取两个向量中的项。
这是我(失败的)尝试在map2
参数中使用funs
的尝试:
mtcars.modified <- mtcars %>%
mutate_at(c("one", "two", "three"),
funs(map2(.x = ., .y = c(mpg, disp, qsec),
~ factor(case_when(
.y < 10 ~ "lt10",
.y >= 10 & .y <= 20 ~ "10to20",
.y > 20 ~ "gt20"),
ordered =T, levels = c("lt10", "10to20", "gt20")))))
我想将所有内容保留在mtcars %>%
管道中,而无需创建命名函数或破坏管道。
答案 0 :(得分:1)
library(tidyverse)
mtcars %>%
dplyr::mutate_at(c("mpg", "disp", "qsec"), cut,
breaks = c(-Inf, 10, 20, Inf),
labels = c("lt10", "10to20", "gt20")) %>%
head()
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 gt20 6 gt20 110 3.90 2.620 10to20 0 1 4 4
#> 2 gt20 6 gt20 110 3.90 2.875 10to20 0 1 4 4
#> 3 gt20 4 gt20 93 3.85 2.320 10to20 1 1 4 1
#> 4 gt20 6 gt20 110 3.08 3.215 10to20 1 0 3 1
#> 5 10to20 8 gt20 175 3.15 3.440 10to20 0 0 3 2
#> 6 10to20 6 gt20 105 2.76 3.460 gt20 1 0 3 1
您可以使用cut function来完成此任务。这是您想要的吗?
如果要保留原始列,并且在修改后的列中需要后缀_mod
,可以执行以下操作:
library(tidyverse)
mtcars %>%
dplyr::mutate_at(c("mpg", "disp", "qsec"),
dplyr::funs(
mod = cut(.,
breaks = c(-Inf, 10, 20, Inf),
labels = c("lt10", "10to20", "gt20")
)
)
) %>%
head()
#> mpg cyl disp hp drat wt qsec vs am gear carb mpg_mod disp_mod
#> 1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 gt20 gt20
#> 2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 gt20 gt20
#> 3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 gt20 gt20
#> 4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 gt20 gt20
#> 5 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 10to20 gt20
#> 6 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 10to20 gt20
#> qsec_mod
#> 1 10to20
#> 2 10to20
#> 3 10to20
#> 4 10to20
#> 5 10to20
#> 6 gt20
答案 1 :(得分:1)
如果使用void coordinates(unsigned int p, int xyz[3])
{
xyz[0] = (p >> 20) & 0x3FF; // Get 10 Bits
if(xyz[0] & 0x200) // Check MSB
xyz[0] |= 0xFFFFFC00; // Sign Extend
xyz[1] = (p >> 10) & 0x3FF;
if(xyz[1] & 0x200)
xyz[1] |= 0xFFFFFC00;
xyz[2] = p & 0x3FF;
if(xyz[2] & 0x200)
xyz[2] |= 0xFFFFFC00;
}
int main(void)
{
int s10[3];
unsigned int u32 = 0xFFFFFFFF;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
u32 = 0x1FF7FDFF;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
u32 = 0x20080200;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
u32 = 0x00000000;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
return 0;
}
函数,则可以在应用函数之前重命名。
dplyr::vars
这也与@seisdrum有关使用mtcars %>%
mutate_at(
vars(one = mpg, two = disp, three = qsec),
funs(
case_when(
. < 10 ~ 'lt10',
. >= 10 & . <= 20 ~ "10to20",
. > 20 ~ 'gt20'
) %>%
ordered(levels = c('lt10', '10to20', 'gt20'))
)
)
base::cut