dplyr-ifelse在mutate using list中

dplyr-ifelse在mutate using list中,r,dplyr,R,Dplyr,给定数据帧df如下 text <- " model,var,value M1,a,12211 M1,b1,10.21 M1,b2,5.07 M1,c1,41.8 M1,c2,58.2 M1,d,1.6 M2,a,11922 M2,b1,15.6 M2,b2,8.9 M2,c1,38.1 M2,c2,61.9 M2,d,1.8 M2,a,13101 M2,b1,9.21 M2,b2,6.56 M2,c1,36.07 M2,c2,63.93 M2,d,1.75 " df <- read.

给定数据帧
df
如下

text <- "
model,var,value
M1,a,12211
M1,b1,10.21
M1,b2,5.07
M1,c1,41.8
M1,c2,58.2
M1,d,1.6
M2,a,11922
M2,b1,15.6
M2,b2,8.9
M2,c1,38.1
M2,c2,61.9
M2,d,1.8
M2,a,13101
M2,b1,9.21
M2,b2,6.56
M2,c1,36.07
M2,c2,63.93
M2,d,1.75
"
df <- read.table(textConnection(text), sep=",", header = T)
预期产量为

   model var    value var2
1     M1   a 12211.00    a
2     M1  b1    10.21    All B
3     M1  b2     5.07    All B
4     M1  c1    41.80    All C
5     M1  c2    58.20    All C
6     M1   d     1.60    d
7     M2   a 11922.00    a
8     M2  b1    15.60    All B
9     M2  b2     8.90    All B
10    M2  c1    38.10    All C
11    M2  c2    61.90    All C
12    M2   d     1.80    d
13    M2   a 13101.00    a
14    M2  b1     9.21    All B
15    M2  b2     6.56    All B
16    M2  c1    36.07    All C
17    M2  c2    63.93    All C
18    M2   d     1.75    d
我计划将dplyr与
ifelse
一起使用,如下所示

df %>%
  mutate(var2 = ifelse(# what should go here )

下面是一个使用
case_当
时的示例解决方案(如注释中所建议):


我简化了你的逻辑——如果我错了,请纠正我

如果
var
=
b
c
后跟数字,则分别替换
所有b
所有c

df %>% 
  mutate(var2 = gsub("^([bc])\\d+", 
                     paste("All", "\\U\\1"), 
                     var, 
                     perl = TRUE))

   model var    value  var2
1     M1   a 12211.00     a
2     M1  b1    10.21 All B
3     M1  b2     5.07 All B
4     M1  c1    41.80 All C
5     M1  c2    58.20 All C
6     M1   d     1.60     d
7     M2   a 11922.00     a
8     M2  b1    15.60 All B
9     M2  b2     8.90 All B
10    M2  c1    38.10 All C
11    M2  c2    61.90 All C
12    M2   d     1.80     d
13    M2   a 13101.00     a
14    M2  b1     9.21 All B
15    M2  b2     6.56 All B
16    M2  c1    36.07 All C
17    M2  c2    63.93 All C
18    M2   d     1.75     d

我们可以创建一个函数,如果
var
存在于
mapping
中,则返回列表名,否则返回
var
。我们可以使用
rowwise()
为每一行执行此函数

get_right_mapping <- function(var) {
   names(which(sapply(mapping, function(x) var %in% x)))
 }

library(dplyr)
df %>%
   rowwise() %>%
   mutate(var2 = ifelse(var %in% unlist(mapping), get_right_mapping(var), var))


#   model var      value  var2 
#   <fct> <chr>    <dbl> <chr>
# 1 M1    a        12211    a    
# 2 M1    b1       10.2  All B
# 3 M1    b2        5.07 All B
# 4 M1    c1       41.8  All C
# 5 M1    c2       58.2  All C
# 6 M1    d        1.60     d    
# 7 M2    a        11922    a    
# 8 M2    b1       15.6  All B
# 9 M2    b2        8.90 All B
#10 M2    c1       38.1  All C
#11 M2    c2       61.9  All C
#12 M2    d         1.80 d    
#13 M2    a         13101    a    
#14 M2    b1        9.21 All B
#15 M2    b2        6.56 All B
#16 M2    c1       36.1  All C
#17 M2    c2       63.9  All C
#18 M2    d         1.75 d    
get_right_映射%
行()
mutate(var2=ifelse(var%in%unlist(mapping),get_right_mapping(var),var))
#模型var值var2
#         
#1 M1 a 12211 a
#2 M1 b1 10.2所有B
#3 M1 b2 5.07全部B
#4 M1 c1 41.8所有C
#5 M1 c2 58.2所有C
#6m1d1.60d
#7平方米a 11922 a
#8平方米b1 15.6所有B
#9平方米b2 8.90所有B
#10平方米c1 38.1所有C
#11平方米c2 61.9所有C
#12平方米直径1.80平方米直径
#13平方米a 13101 a
#14平方米b1 9.21所有B
#15平方米b2 6.56所有B
#16平方米c1 36.1所有C
#17平方米c2 63.9所有C
#18平方米直径1.75平方米直径
数据

mapping <- c( "All A"= list(c('a1', 'a2')), "All B" = list(c('b1', 'b2')), 
              "All C" = list(c('c1','c2')))
df$var <- as.character(df$var)

mapping另一方面,如果将
mapping
转换为
data.frame
collect
值,则会有少量使用的
级别

library(tidyverse)
as_tibble(mapping) %>% rename_all(~paste0("All_",.x)) %>%
  gather(var2,var) %>% right_join(df) %>%   # main chunk
  mutate(var2=ifelse(is.na(var2),var,var2)) # replace nas

# # A tibble: 18 x 4
#     var2   var  model    value
#    <chr> <chr> <fctr>    <dbl>
#  1     a     a     M1 12211.00
#  2 All_B    b1     M1    10.21
#  3 All_B    b2     M1     5.07
#  4 All_C    c1     M1    41.80
#  5 All_C    c2     M1    58.20
#  6     d     d     M1     1.60
#  7     a     a     M2 11922.00
#  8 All_B    b1     M2    15.60
#  9 All_B    b2     M2     8.90
# 10 All_C    c1     M2    38.10
# 11 All_C    c2     M2    61.90
# 12     d     d     M2     1.80
# 13     a     a     M2 13101.00
# 14 All_B    b1     M2     9.21
# 15 All_B    b2     M2     6.56
# 16 All_C    c1     M2    36.07
# 17 All_C    c2     M2    63.93
# 18     d     d     M2     1.75
库(tidyverse)
as_tible(mapping)%%>%rename_all(~paste0(“all_”,.x))%%>%
聚集(var2,var)%>%右键连接(df)%>%主块
变异(var2=ifelse(is.na(var2),var,var2))#替换nas
##tibble:18x4
#var2 var模型值
#          
#1A M1 12211.00
#2所有_B b1 M1 10.21
#3所有B b2 M1 5.07
#4所有_C c1 M1 41.80
#5所有_C c2 M1 58.20
#6D M1 1.60
#7 a M2 11922.00
#8所有地下室1平方米15.60
#9所有B b2 M2 8.90
#10所有C 1平方米38.10
#11所有建筑面积c2平方米61.90
#12 d M2 1.80
#13 a M2 13101.00
#14所有地下室b1 M2 9.21
#15所有b2平方米6.56
#16所有地下室c1平方米36.07
#17所有建筑面积c2平方米63.93
#18d M2 1.75

您还可以建议如何使用所包含的
映射
列表动态拾取
var2
values@eipi10当
发生时,您的
case_代码出现以下错误:“错误:'match'需要向量参数”。你以前见过这个吗?另外,
mutate
函数缺少一个尾随“)”。
var==“b1”| var==“b2”
也是%c(“b1”,“b2”)
中的
var%;顺便说一句,@steveb遇到的错误源于
var
是一个
因子,因此我们需要首先将
var
转换为
字符
如果var=b或c后跟数字,则分别替换全部b或全部c。
对于示例数据来说是可以的,但实际数据中可能不存在这样的模式。因此,%映射[['All A']
中的
var%这类逻辑更合适。因此,最好看看
var
可以在实际数据中包含哪些值。
mapping <- c( "All A"= list(c('a1', 'a2')), "All B" = list(c('b1', 'b2')), 
              "All C" = list(c('c1','c2')))
df$var <- as.character(df$var)
mapping <- c("B"= list(c('b1', 'b2')), "C" = list(c('c1', 'c2')))

df$var2 <- df$var
othval  <- setdiff(df$var, unlist(mapping))
levels(df$var2) <- c(mapping, setNames(othval,othval))
# [1] a B B C C d a B B C C d a B B C C d
#Levels: B C a d
library(tidyverse)
as_tibble(mapping) %>% rename_all(~paste0("All_",.x)) %>%
  gather(var2,var) %>% right_join(df) %>%   # main chunk
  mutate(var2=ifelse(is.na(var2),var,var2)) # replace nas

# # A tibble: 18 x 4
#     var2   var  model    value
#    <chr> <chr> <fctr>    <dbl>
#  1     a     a     M1 12211.00
#  2 All_B    b1     M1    10.21
#  3 All_B    b2     M1     5.07
#  4 All_C    c1     M1    41.80
#  5 All_C    c2     M1    58.20
#  6     d     d     M1     1.60
#  7     a     a     M2 11922.00
#  8 All_B    b1     M2    15.60
#  9 All_B    b2     M2     8.90
# 10 All_C    c1     M2    38.10
# 11 All_C    c2     M2    61.90
# 12     d     d     M2     1.80
# 13     a     a     M2 13101.00
# 14 All_B    b1     M2     9.21
# 15 All_B    b2     M2     6.56
# 16 All_C    c1     M2    36.07
# 17 All_C    c2     M2    63.93
# 18     d     d     M2     1.75