【问题标题】:Using names of sorted variables within mutate and ifelse在 mutate 和 ifelse 中使用排序变量的名称
【发布时间】:2021-12-11 23:35:33
【问题描述】:

我有以下示例数据:

id <- c(1, 2, 3)
ex3 <- c(0.8,   0.2, 0.3)
ex2 <- c(0.1,   0.4, 0.04)
ex1 <- c(0.04,  0.3, 0.5)
ex <- c(1, 1, 1)
ran <- c(0.5, 0.7, 0.6)
dat <- data.frame(id, ex1, ex2, ex3, ex, ran)

dat

  id  ex1  ex2 ex3 ex ran
1  1 0.04 0.10 0.8  1 0.5
2  2 0.30 0.40 0.2  1 0.7
3  3 0.50 0.04 0.3  1 0.6

我想通过 dplyr/tidyr 使用以下代码修改变量“ex”:

library(dplyr)
library(tidyr)

dat %>% 
  pivot_longer(
    cols = ex1:ex3
  ) %>% 
  arrange(id, desc(value)) %>% 
  group_by(id) %>% 
  mutate(ex = ifelse(ran <= value[1] & ran > sum(value[2], value[3]), 5, ex)) %>% 
  pivot_wider(
    names_from=name
  )

# A tibble: 3 x 6
# Groups:   id [3]
     id    ex   ran   ex3   ex2   ex1
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     1     5   0.5   0.8  0.1   0.04
2     2     1   0.7   0.2  0.4   0.3 
3     3     1   0.6   0.3  0.04  0.5

是否可以在 mutate 的 ifelse 语句中使用“ex1”-“ex3”的名称作为“ex”的新值而不是“5”?示例:使用 ex$-variables 的名称作为新值会导致以下输出:

  id ex3  ex2  ex1  ex ran
1  1 0.8 0.10 0.04 ex3 0.5
2  2 0.2 0.40 0.30   1 0.7
3  3 0.3 0.04 0.50   1 0.6

或者使用 ex$-variables 的数量导致这个输出:

  id ex3  ex2  ex1  ex ran
1  1 0.8 0.10 0.04   3 0.5
2  2 0.2 0.40 0.30   1 0.7
3  3 0.3 0.04 0.50   1 0.6

或者如果我想将最低值作为“ex”的新值(因为它是“ex2”):

  id ex3  ex2  ex1  ex ran
1  1 0.8 0.10 0.04   1 0.5
2  2 0.2 0.40 0.30   1 0.7
3  3 0.3 0.04 0.50   1 0.6

总结一下:我想引用排序后的“ex$”值的变量名,以便在 mutate 中的 ifelse 中为“ex”创建新值。

【问题讨论】:

    标签: r dplyr tidyr


    【解决方案1】:

    一种方法是使用readr 包中的parse_number 从ex1、ex2、ex3 中提取数字。根据您可以执行的逻辑:

    parse_number(name[1]) 这里 1 是列中的位置,您可以使用 2 或 3 取决于最适合您的逻辑。

    library(dplyr)
    library(tidyr)
    library(readr)
    
    dat %>% 
      pivot_longer(
        cols = ex1:ex3
      ) %>% 
      arrange(id, desc(value)) %>% 
      group_by(id) %>% 
      mutate(ex = ifelse(ran <= value[1] & ran > sum(value[2], value[3]), parse_number(name[3]), ex)) %>% 
      pivot_wider(
        names_from=name
      )
    
    
       id    ex   ran   ex1   ex2   ex3
      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    1     1     3   0.5   0.8  0.1   0.04
    2     2     1   0.7   0.2  0.4   0.3 
    3     3     1   0.6   0.3  0.04  0.5 
    

    全名:

    mibrary(dplyr)
    library(tidyr)
    library(readr)
    
    dat %>% 
      pivot_longer(
        cols = ex1:ex3
      ) %>% 
      arrange(id, desc(value)) %>% 
      group_by(id) %>% 
      mutate(ex = ifelse(ran <= value[1] & ran > sum(value[2], value[3]), name[1], as.character(ex))) %>% 
      pivot_wider(
        names_from=name
      )
    
         id ex      ran   ex1   ex2   ex3
      <dbl> <chr> <dbl> <dbl> <dbl> <dbl>
    1     1 ex1     0.5   0.8  0.1   0.04
    2     2 1       0.7   0.2  0.4   0.3 
    3     3 1       0.6   0.3  0.04  0.5 
    

    【讨论】:

    • 我不知道为什么,但对我来说“mutate(ex = ifelse(ran sum(value[2], value[3]), parse_number( name[3]), ex))" 不会导致您的输出;它导致“ex”的 c(1, 1, 1)。
    • 你有library(readr)
    • 是的,也没有错误或其他任何东西;我正在使用相同的代码。也许你可以用我上面的示例数据再试一次?我不得不在发布后几分钟更改它。
    • 这段代码与上述数据集:dat %&gt;% pivot_longer( cols = ex1:ex3 ) %&gt;% arrange(id, desc(value)) %&gt;% group_by(id) %&gt;% mutate(ex = ifelse(ran &lt;= value[1] &amp; ran &gt; sum(value[2], value[3]), parse_number(name[1]), ex)) %&gt;% pivot_wider( names_from=name )
    • 现在我可以看到问题了:在你的回答中你写: mutate(ex = ifelse(ran sum(value[2], value[3]), parse_number(name[3]), ex));并在工作评论中: mutate(ex = ifelse(ran sum(value[2], value[3]), parse_number(name[1]), ex))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多