【问题标题】:R: Generate a dummy variable based on the existence of one column' value in another columnR:根据另一列中存在的一列值生成一个虚拟变量
【发布时间】:2020-05-24 17:52:59
【问题描述】:

我有一个这样的数据框:

A                    B          
2012,2013,2014     2011
2012,2013,2014     2012
2012,2013,2014     2013
2012,2013,2014     2014
2012,2013,2014     2015

我想创建一个虚拟变量,表示A列中B列的值是否存在。1表示存在,0表示不存在。这样,

A                    B       dummy        
2012,2013,2014     2011        0
2012,2013,2014     2012        1
2012,2013,2014     2013        1
2012,2013,2014     2014        1
2012,2013,2014     2015        0

我曾尝试使用%in% 来实现:

df$dummy <- ifelse(df$B %in% df$A, 1, 0)

但原来dummy这一列的所有内容都是1

当我尝试使用另一种方法时发生同样的情况any()

df$dummy <- any(df$A==df$B)

dummy 列中的所有内容都是TRUE

有没有一种有效的方法来生成这个虚拟变量?

非常感谢!

【问题讨论】:

    标签: r if-statement dummy-variable any


    【解决方案1】:

    看起来A 列是用逗号分隔的数字字符串,因此%in% 不合适(例如,如果您在多个字符串的向量中检查B,这将很有帮助,如果AB 是数字,则为数字)。如果您的数据框结构不同,请告诉我(并随时编辑您的问题)。

    您可能可以通过多种方式完成此操作。也许一种简单的方法是一次使用grepl 一行来识别B 列是否存在于A 中。

    library(tidyverse)
    
    df %>%
      rowwise() %>%
      mutate(dummy = +grepl(B, A))
    

    输出

    # A tibble: 5 x 3
      A              B     dummy
      <fct>          <fct> <int>
    1 2012,2013,2014 2011      0
    2 2012,2013,2014 2012      1
    3 2012,2013,2014 2013      1
    4 2012,2013,2014 2014      1
    5 2012,2013,2014 2015      0
    

    数据

    df <- data.frame(
      A = c(rep("2012,2013,2014", 5)),
      B = c("2011", "2012", "2013", "2014", "2015")
    )
    

    【讨论】:

      【解决方案2】:

      如果你想使用基础 R:

      df <- data.frame(A = rep("2012,2013,2014", 5), B = c("2011", "2012","2013","2014","2015"))
      
      for(i in 1:nrow(df)){
           df$dummy[i] <- grepl(df$B[i],df$A[i])
      }
      

      【讨论】:

        【解决方案3】:

        制作一个制表符分隔的文件:

        A   B          
        2012,2013,2014  2011
        2012,2013,2014  2012
        2012,2013,2014  2013
        2012,2013,2014  2014
        2012,2013,2014  2015
        

        这是使用来自stringrstr_detect 的一种方式:

        read.table('test.txt', header = TRUE) %>% 
          mutate(
            B = as.character(B),
            dummy = case_when(
              str_detect(pattern = B, fixed(A)) ~ '1',
              TRUE ~ '0'
            )
          )
        

        【讨论】:

          【解决方案4】:

          这是另一个使用tidyverse 的解决方案。主要问题是A 被读取为字符串。我的解决方案首先将每个数字分成不同的列,然后将B 与这些数字进行比较。

          library(tidyverse)
          
          df %>%
            #Separate A into separate numbers
            separate(col = A,
                     sep = ",",
                     into = c("S1","S2","S3")) %>%
            #Compare B to the new columns and fill dummy
            mutate(dummy = ifelse(B %in% c(S1,S2,S3), 1, 0))
          

          【讨论】:

          • 感谢乔纳森的评论。上面的列 A 只是一个示例 - 实际数据框中的该列可能有更多/少于 3 个数字。所以我想一种更自动化的方式会更好地解决这个问题。我已经有了答案,不过还是谢谢!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-10
          • 1970-01-01
          相关资源
          最近更新 更多