【问题标题】:R find value in dataframe (rowwise for factor variables)R在数据框中找到值(因子变量的行)
【发布时间】:2020-06-14 15:55:58
【问题描述】:

我有一个带有像这样的字符串(因子)变量的df

id v1 v2 v3 v4
1  1  1  1  0
1  0  0  0  0
1  1  1  1  0
1  1  1  1  0
1  1  1  1  0

我想要创建一个等于 1 或 0(数字)的新列,如果 1 出现在列列表中,例如 (v2, v3, v4)

id v1 v2 v3 v4 lu
1  1  1  1  0  1
2  0  0  0  0  0
3  1  1  1  0  1
4  0  0  1  0  1
5  1  0  1  0  1

我不想转换为数字(因为我需要它们以供将来分析)所以像

df <- df %>% mutate(lu = select(., v2:v4) %>% rowSums(na.rm = TRUE))
df <- df %>% mutate(lu = if_else(lu_1 > 0, 1, lu))

不可能。实际上要考虑的变量列表相当长(大约 150 个)

谢谢!

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    您好,我不知道您是否想要这样的东西。我不擅长 dplyr 所以这里是一个基本的 R 版本

    虚拟数据:

    a <-as.character(sample(0:1,100,replace = T))
    b <-as.character(sample(0:1,100,replace = T))
    c <-as.character(sample(0:1,100,replace = T))
    d <-as.character(sample(0:1,100,replace = T))
    
    df <- as.data.frame(cbind(a,b,c,d), stringsAsFactors = T)
    

    实际代码:

    test <- function(x) {
      out <- sum(as.numeric(x))
      ifelse(out>0,1,0)
    }
    
    df$lu <- as.factor(apply(df,MARGIN = 1, test))
    

    输出:

    id  a   b   c   d   lu
    1   0   1   0   0   1
    2   0   1   0   0   1
    3   0   1   0   0   1
    4   0   1   0   1   1
    5   0   0   0   0   0
    

    【讨论】:

    • 您好,欢迎来到 SO,发布非 dplyr 代码没问题!
    • 在我的虚拟数据中我将它设置为.character 如果我运行“class()”它返回“character”
    • 不,我认为您的代码运行良好,只是我的 dplyr 本能起作用,我认为 apply 的行为略有不同
    • 谢谢你,在过去的几天里我做了一些申请,你对此有什么感觉,而且我“应该把那个“ifelse”包装在一个“return()”中
    • 我想我希望转换为数字来生成 1 和 2 而不是 0 和 1
    【解决方案2】:

    只是

    df$lu <- as.numeric(rowSums(df[,3:5]=="1")>0)
    

    或者,像 sharmajee499

    df %>%
      mutate(lu=as.numeric(rowSums(df[,3:5]=="1")>0))
    

    【讨论】:

      【解决方案3】:

      计算起来也可能非常昂贵

      library(tidyverse)
      
      
      
      df_example <- data.table::fread("id v1 v2 v3 v4
      1  1  1  1  0
      1  0  0  0  0
      1  1  1  1  0
      1  1  1  1  0
      1  1  1  1  0") %>% tibble()
      
      
      df_example %>%
        mutate(across(-id,.fns = as_factor)) %>% 
        rowwise() %>% 
        mutate(lu = c_across(-id) %>%
                 as.character() %>%
                 as.numeric() %>%
                 sum()) %>% 
        mutate(expensive = if_else(lu == 0,0,1))
      #> # A tibble: 5 x 7
      #> # Rowwise: 
      #>      id v1    v2    v3    v4       lu expensive
      #>   <int> <fct> <fct> <fct> <fct> <dbl>     <dbl>
      #> 1     1 1     1     1     0         3         1
      #> 2     1 0     0     0     0         0         0
      #> 3     1 1     1     1     0         3         1
      #> 4     1 1     1     1     0         3         1
      #> 5     1 1     1     1     0         3         1
      

      reprex package (v0.3.0) 于 2020 年 6 月 13 日创建

      这可能会快一点

      df_example %>%
        mutate(across(-id,.fns = as_factor)) %>% 
        mutate(lu = rowSums(across(-id, .fns = ~ .x %>% as.character() %>% as.numeric()))) %>% 
        mutate(lu = if_else(lu == 0,0,1))
      

      【讨论】:

        【解决方案4】:

        首先创建一个新列来对行求和,例如:

        df<- df %>% mutate(sum= rowSums(df[,2:5])
        

        之后,您可以对该列执行if 条件以创建新列:

        df<- df %>% mutate(lu= ifelse(sum>=1,1,0))
        

        【讨论】:

          【解决方案5】:

          使用dplyr 1.0,可以使用across()转换成数字,然后应用rowSums()

          df %>%
            mutate(lu = rowSums(across(starts_with("v"), .fns = as.numeric)))
          

          如果我们更喜欢二元结果,我们的新列中有总和:

          df %>%
            mutate(lu = 1*(rowSums(across(starts_with("v"), .fns = as.numeric)) > 0))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-15
            • 1970-01-01
            • 2016-03-09
            • 2019-06-22
            • 1970-01-01
            • 2011-06-15
            相关资源
            最近更新 更多