首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在mutate和case_when函数中将映射函数应用于动态列名?

如何在mutate和case_when函数中将映射函数应用于动态列名?
EN

Stack Overflow用户
提问于 2019-07-19 11:55:12
回答 1查看 339关注 0票数 0

这是我拥有的数据框:

代码语言:javascript
运行
复制
df <- data.frame(
  id       = c(1,2,3,4,5),
  a_1_area = c(3,10,4,0,15),
  a_2_area = c(2,1,1,0,3),
  a_3_area = c(12,3,0,3,1),
  a_4_area = c(9,7,8,0,0),
  a_5_area = c(1,2,0,2,2)
  )

将自定义范围添加到df中,以便在ggplot2中绘制条形图:

代码语言:javascript
运行
复制
    df %>% mutate(a_1_range=case_when(
  a_1_area == 0 ~ "0",
  a_1_area >= 1  & a_1_area < 5 ~ "1-4",
  a_1_area >= 5  & a_1_area <10 ~ "5-9",
  a_1_area >= 10 & a_1_area <15 ~ "10-14",
  a_1_area >= 15                ~ "15-",
  TRUE ~ "999")
  )

输出:

代码语言:javascript
运行
复制
  id a_1_area a_2_area a_3_area a_4_area a_5_area a_1_range
1  1        3        2       12        9        1       1-5
2  2       10        1        3        7        2      6-10
3  3        4        1        0        8        0       1-5
4  4        0        0        3        0        2         0
5  5       15        3        1        0        2     11-15

我继续对其余列执行此操作:a_2_areaa_3_areaa_4_areaa_5_area,使用for循环。

代码语言:javascript
运行
复制
for (i in 1:5) {
  df %>% mutate(!!colname[i]:=case_when(
    !!sym(varname[i]) == 0                          ~ "0",
    !!sym(varname[i]) >= 1  & !!sym(varname[i]) < 5 ~ "1-4",
    !!sym(varname[i]) >= 5  & !!sym(varname[i]) <10 ~ "5-9",
    !!sym(varname[i]) >= 10 & !!sym(varname[i]) <15 ~ "10-14",
    !!sym(varname[i]) >= 15                          ~ "15-",
    TRUE ~ "999")) -> df
  }

输出:

代码语言:javascript
运行
复制
  id a_1_area a_2_area a_3_area a_4_area a_5_area a_1_range a_2_range a_3_range a_4_range
1  1        3        2       12        9        1       1-4       1-4     10-14       5-9
2  2       10        1        3        7        2     10-14       1-4       1-4       5-9
3  3        4        1        0        8        0       1-4       1-4         0       5-9
4  4        0        0        3        0        2         0         0       1-4         0
5  5       15        3        1        0        2       15-       1-4       1-4         0
  a_5_range
1       1-4
2       1-4
3         0
4       1-4
5       1-4

另一方面,在purrr中使用map进行同样的操作也是可能的;但是我仍然不能将其应用于动态变量。你对此有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-19 12:04:21

我认为cut可能是个不错的选择

代码语言:javascript
运行
复制
cols <- grep("area$", names(df), value = TRUE)

df[paste0(cols, "_range")] <- lapply(df[cols], function(x) cut(x,
           breaks = c(0, 1, 5, 10, 15, Inf), 
           labels = c("0", "1-4", "5-9", "10-14", "15-"), include.lowest = TRUE))

它还可以集成到dplyr

代码语言:javascript
运行
复制
library(dplyr)
df %>%
   mutate_at(vars(ends_with("area")), list(range = ~cut(., 
                   breaks = c(0, 1, 5, 10, 15, Inf), 
            labels = c("0", "1-4", "5-9", "10-14", "15-"), include.lowest = TRUE)))

或者,如果您更喜欢使用case_when,则可以使用mutate_at,它将在多个列上运行相同的函数,这样您就不必使用for循环

代码语言:javascript
运行
复制
df %>% mutate_at(vars(ends_with("area")), list(area = 
       ~case_when(. == 0 ~ "0",
                  . >= 1  & . < 5 ~ "1-4",
                  . >= 5  & . <10 ~ "5-9",
                  . >= 10 & . <15 ~ "10-14",
                  . >= 15 ~ "15-",
                  TRUE ~ "999")))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57105306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档