【问题标题】:How to check if values in one dataframe exist in another dataframe in R?如何检查一个数据框中的值是否存在于R中的另一个数据框中?
【发布时间】:2020-12-08 20:44:42
【问题描述】:

假设我们有一个这样的数据框:

id  reply  user_name
1   NA     John
2   NA     Amazon
3   NA     Bob

还有一个像这样的数据框:

name  organisation
John  Amazon
Pat   Apple

如果第 3 列中的值与第二个数据框中的第 1 列或第 2 列匹配,有没有办法用 'True''False' 填充第一个数据框中的 reply 列?例如,由于第二个数据帧中的JohnAmazon 存在于第一个数据帧中,我希望第一个数据帧这样更新:

id  reply  user_name
1   True   John
2   True   Amazon
3   False  Bob

【问题讨论】:

    标签: r function dataframe loops


    【解决方案1】:

    尝试使用%in% 和所有值的向量:

    #Code
    df1$reply <- df1$user_name %in% c(df2$name,df2$organisation)
    

    输出:

    df1
      id reply user_name
    1  1  TRUE      John
    2  2  TRUE    Amazon
    3  3 FALSE       Bob
    

    使用的一些数据:

    #Data1
    df1 <- structure(list(id = 1:3, reply = c(NA, NA, NA), user_name = c("John", 
    "Amazon", "Bob")), class = "data.frame", row.names = c(NA, -3L
    ))
    
    #Data2
    df2 <- structure(list(name = c("John", "Pat"), organisation = c("Amazon", 
    "Apple")), class = "data.frame", row.names = c(NA, -2L))
    

    【讨论】:

    • 谢谢!这是我想要的输出,但是当我尝试使用完整的数据集时,我得到了这个错误:Error in $(*tmp*, reply, value = logical(0)) : replacement has 0 rows, data has 221711。知道如何解决吗?
    • 原始数据集中的名称不同,是的,但我编辑了代码以匹配名称。这里数据中的reply列是全数据集中的逻辑类型。
    • @HelpMe 试试df1$reply[is.na(df1$reply)] &lt;- df1$user_name %in% c(df2$name,df2$organisation)
    • 列中的所有值都只是 NA
    • 使用您的is.na 解决方案,我收到不同的错误消息:replacement has length zero。任何想法为什么会发生这种情况?
    【解决方案2】:

    我们可以在base R中使用%in%

    df1$reply <- df1$user_name %in%  unlist(df2)
    

    如果我们想改变逻辑到字符串的格式

    df1$reply <- sub("^(.)(.*)", "\\1\\L\\2", df1$reply, perl = TRUE)
    df1$reply
    #[1] "True"  "True"  "False"
    

    数据

    df1 <- structure(list(id = 1:3, reply = c(NA, NA, NA), user_name = c("John", 
    "Amazon", "Bob")), class = "data.frame", row.names = c(NA, -3L
    ))
    
    df2 <- structure(list(name = c("John", "Pat"), organisation = c("Amazon", 
    "Apple")), class = "data.frame", row.names = c(NA, -2L))
    

    【讨论】:

      【解决方案3】:

      您可以通过以下方式使用 3 行代码获得所需的准确输出!

      df1 <- data.frame(id = 1:3, reply = NA, user.name = c("John", "Amazon", "Bob"), stringsAsFactors = F)
      df2 <- data.frame(id = 1:2, name = c("John", "Pat"), organisation = c("Amazon", "Apple"), stringsAsFactors = F)
      
      df1$reply <- df1$user.name %in%  unlist(df2) %>% as.character() %>% str_to_title() 
      

      输出

      id reply user.name
       1  True      John
       2  True    Amazon
       3 False       Bob
      

      您将需要 dplyrmagrittrstringr 包,我强烈推荐使用这些包来处理各种数据。

      【讨论】:

        【解决方案4】:

        在第一个答案的基础上,你也可以用整洁的方式解决这个问题。

        #Building your dataframes
        df1 <- data.frame(id = 1:3, reply = NA, user.name = c("John", "Amazon", "Bob"), stringsAsFactors = F)
        df2 <- data.frame(id = 1:2, name = c("John", "Pat"), organisation = c("Amazon", "Apple"), stringsAsFactors = F)
        
        
          df1 %>%
            mutate(reply = user.name %in% c(df2$name, df2$organisation))
        
        

        我个人喜欢整洁的解决方案,因为这样您就可以轻松地通过结果来获得更多见解——例如,如果您想知道有多少人回复了,只需多写一行:

          df1 %>%
            mutate(reply = user.name %in% c(df2$name, df2$organisation)) %>%
            summarize(reply_sum = sum(reply))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-07
          • 1970-01-01
          • 2022-01-18
          • 1970-01-01
          • 2021-12-25
          • 2021-09-06
          • 1970-01-01
          相关资源
          最近更新 更多