【问题标题】:Create new variable based on other variables基于其他变量创建新变量
【发布时间】:2018-10-31 10:17:17
【问题描述】:

在 R 中工作,我有一个包含三个变量的数据框,如下所示:

  var1        var2        var3       
1 0.695783133 0.009036145 0.02409639 
2 0.651006711 0.348993289 0.00000000 
3 1.000000000 0.000000000 0.00000000 
4 0.404185022 0.575991189 0.00000000 
5 0.004863813 0.736381323 0.25097276 
6 0.833827893 0.074183976 0.06231454 

我想通过以下方式添加第四个变量(var4),其值将基于原始三个变量(var1var2var3)的值:

如果var1 >= 0.5,var4 = 1

如果var2 >= 0.5,var4 = 2

如果var3 >= 0.5,var4 = 3

如果没有变量 >= 0.5,var4 = 4

例如像这样:

  var1        var2        var3       var4
1 0.695783133 0.009036145 0.02409639 1
2 0.651006711 0.348993289 0.00000000 1
3 1.000000000 0.000000000 0.00000000 1
4 0.404185022 0.575991189 0.00000000 2
5 0.004863813 0.736381323 0.25097276 2
6 0.833827893 0.074183976 0.06231454 1

我相信有一个简单的方法可以做到这一点,但我无法弄清楚,因为我对 R 很陌生。关于如何做到这一点有什么建议吗?

【问题讨论】:

    标签: r dataframe categories


    【解决方案1】:

    鉴于 var1 在第一个位置,var2 在第二个位置,依此类推,那么您可以使用 max.colifelse 来捕捉您的最后一个条件,即

    ifelse(rowSums(df >= 0.5) == 0, 4, max.col(df >= 0.5))
    #if 0.5 is the maximum value then ifelse(rowSums(df >= 0.5) == 0,4,max.col(df)) will also do
    #1 2 3 4 5 6 
    #1 1 1 2 2 1
    

    【讨论】:

    • 这很好用,谢谢。我认为有必要使用ifelse 来捕捉我的最后​​一个条件,但是当我自己编写它时并没有让它工作。再次感谢!
    • @m.ras ifelse 不是必需品,max.col(df >= 0.5, ties.method = "first") + 3*(rowSums(df >= 0.5) == 0) 应该给出相同的输出
    • @Jaap 谢谢!我也会试试的。
    • @Jaap 我试过你的建议,效果也很好。但是,我不完全理解脚本的第二部分的作用(即+ 3*(rowSums(df >= 0.5) == 0) 部分)。更具体地说,您为什么要使用3* rowSums 功能?您介意向我解释一下,还是指出我可以阅读更多相关信息的正确方向?谢谢。
    【解决方案2】:

    tidyverse:

    library(tidyverse)
     df <- read.table(text=" var1        var2        var3       
                1 0.695783133 0.009036145 0.02409639 
                2 0.651006711 0.348993289 0.00000000 
                3 1.000000000 0.000000000 0.00000000 
                4 0.404185022 0.575991189 0.00000000 
                5 0.004863813 0.736381323 0.25097276 
                6 0.833827893 0.074183976 0.06231454 ")
     df%>%
       mutate(var4=case_when(
         var1>=.5 ~ 1,
         var2>=.5 ~ 2,
         var3>=.5 ~ 3,
         T~4))
             var1        var2       var3 var4
    1 0.695783133 0.009036145 0.02409639    1
    2 0.651006711 0.348993289 0.00000000    1
    3 1.000000000 0.000000000 0.00000000    1
    4 0.404185022 0.575991189 0.00000000    2
    5 0.004863813 0.736381323 0.25097276    2
    6 0.833827893 0.074183976 0.06231454    1
    

    【讨论】:

      【解决方案3】:

      使用 Base r ifelse 可以解决问题

      df_test<- read.table(text= "var1        var2        var3       
      1 0.695783133 0.009036145 0.02409639 
      2 0.651006711 0.348993289 0.00000000 
      3 1.000000000 0.000000000 0.00000000 
      4 0.404185022 0.575991189 0.00000000 
      5 0.004863813 0.736381323 0.25097276 
      6 0.833827893 0.074183976 0.06231454 ",header = T)
      
      df_test$var4 <- ifelse(df_test$var1 > 0.5,1,ifelse(df_test$var2 > 0.5,2,ifelse(df_test$var3 > 0.5,3,4)))
      

      【讨论】:

        【解决方案4】:

        可能是这样的:

        sapply(apply(df >= .5, 1, which), function(x) if(length(x)) x[1] else 4)
        

        【讨论】:

        • @AndreElrico 抱歉。下次我发帖时会确保提供更好的数据。谢谢你帮助我。
        • @Sotos 现在可以了
        【解决方案5】:

        如果您提供数据供我们使用,使用 dput() 会有所帮助。

        但是,也许像这样使用 dplyr。

        df <- df %>% 
          mutate(var4 = case_when (var1 >= 0.5 ~ 1,
                                   var2 >= 0.5 ~ 2,
                                   var3 >= 0.5 ~ 3,
                                   TRUE ~ 4)
        

        【讨论】:

        • 什么是=&gt;,你的意思是&gt;=
        • 是的,这就是我的意思。现在改了。
        猜你喜欢
        • 2021-02-10
        • 2021-02-09
        • 1970-01-01
        • 2015-08-01
        • 2018-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-02
        相关资源
        最近更新 更多