当前位置: 首页 > 知识库问答 >
问题:

dplyr - ifelse in mutate using list

秦英发
2023-03-14

给定数据帧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)

我想通过dplyr mutate基于< code>var的值添加一个col var2

基于以下逻辑。

如果var='b1'var='b2'全部B,如果var='c1'var='c2'All C否则变量

我想按如下方式存储映射,并使用它来构建上述逻辑

mapping <- c("All B"= list(c('b1', 'b2')), "All C" = list(c('c1', 'c2')))
> mapping    
$`All B`
[1] "b1" "b2"

$`All C`
[1] "c1" "c2"

预期输出为

   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与< code>ifelse一起使用,如下所示

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

共有3个答案

拓拔高畅
2023-03-14

顺便说一下,有一个很少使用的< code >级别

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

(这里的大部分内容都是说明< code>mapping没有涵盖的情况)

赵浩邈
2023-03-14

我们可以创建一个函数,如果var存在于映射中,则返回列表名称,否则它返回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    

数据

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)
阎伟志
2023-03-14

下面是一个使用<code>case_when</code>的示例解决方案(如注释中所建议的):

df %>%
    mutate(
        var = as.character(var),
        var2 = case_when(
            var == "b1" | var == "b2" ~ "All B",
            var == "c1" | var == "c2" ~ "All C",
            TRUE ~ var))
#   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    
 类似资料:
  • 我有一个dataframe和要删除dataframe中的列列表。让我们使用数据集作为示例。我希望删除和,只使用剩余的列。如何使用或从包中执行此操作? drop.cols中的错误:参数类型无效 我觉得我错过了一些明显的东西,因为这些看起来像是一个相当有用的操作,应该已经存在了。在Github上,有人发布了一个类似的问题,Hadley说要使用“负面索引”。那是(我想)我试过的,但没有效果。有什么建议吗

  • 大家早上好,这是我第一次在stack overflow上发帖。感谢任何帮助! 我有2个用于分析股票数据的数据框。一个数据框包含日期和其他信息,我们可以将其称为df: 第二个数据框也有日期和其他重要信息。 这是我想做的:对于df1中的每一行,我需要: -在df2中查找日期,当df2$答案与df1$key相同时,它最接近df1中该行的日期。 -然后提取df2中该行的另一列的信息,并将其放入df1中的新

  • 简单地说,我需要将一系列列中的值与一个“基线”列进行比较。当列中的值高于基线时,我需要使用基线值。当列中的值低于或等于基线时,我需要保留该值。下面是一个示例数据集(我的实际数据集要大得多): 我当前的代码使用mutate_at()并且运行良好: 但是当我试图更新它以反映DPLYR1.0中的跨()时,我总是得到一个错误。以下是我的尝试: 你知道我做错了什么吗?case_when()是否适用于交叉?

  • 我到处都找不到答案。 问候

  • 问题内容: 有没有一种方法可以强制断开与对象的连接? 参见例如: 附带一提,它会在几秒钟后很快自动断开连接: 之后,您可以再次运行该命令。 问题答案: 你可以做: 强制断开连接。 这就是通过(通过源文件)此函数中的垃圾回收所需要的: