【问题标题】:Create column based on presence of string pattern and ifelse根据字符串模式和 ifelse 的存在创建列
【发布时间】:2014-08-18 21:10:27
【问题描述】:

如果模式匹配,我想用两个值之一填充新列。

这是我的数据框:

df <- structure(list(loc_01 = c("apis", "indu", "isro", "miss", "non_apis", 
"non_indu", "non_isro", "non_miss", "non_piro", "non_sacn", "non_slbe", 
"non_voya", "piro", "sacn", "slbe", "voya"), loc01_land = c(165730500, 
62101800, 540687600, 161140500, 1694590200, 1459707300, 1025051400, 
1419866100, 2037064500, 2204629200, 1918840500, 886299300, 264726000, 
321003900, 241292700, 530532000)), class = "data.frame", row.names = c(NA, 
-16L), .Names = c("loc_01", "loc01_land"))

看起来像这样……

     loc_01 loc01_land
1      apis  165730500
2      indu   62101800
3      isro  540687600
4      miss  161140500
5  non_apis 1694590200
6  non_indu 1459707300
7  non_isro 1025051400
8  non_miss 1419866100
9  non_piro 2037064500
10 non_sacn 2204629200
11 non_slbe 1918840500
12 non_voya  886299300
13     piro  264726000
14     sacn  321003900
15     slbe  241292700
16     voya  530532000

我想在df 中添加一个名为“loc_01”的列。如果loc_01包含non,则返回'outside',如果不包含non,则返回'inside'。这是我的 ifelse 语句,但我遗漏了一些东西,因为它只返回 false 值。

df$loc01 <- ifelse(df$loc_01 == "non", 'outside', 'inside')

以及由此产生的 df...

     loc_01 loc01_land  loc01
1      apis  165730500 inside
2      indu   62101800 inside
3      isro  540687600 inside
4      miss  161140500 inside
5  non_apis 1694590200 inside
6  non_indu 1459707300 inside
7  non_isro 1025051400 inside
8  non_miss 1419866100 inside
9  non_piro 2037064500 inside
10 non_sacn 2204629200 inside
11 non_slbe 1918840500 inside
12 non_voya  886299300 inside
13     piro  264726000 inside
14     sacn  321003900 inside
15     slbe  241292700 inside
16     voya  530532000 inside

谢谢 -al

【问题讨论】:

    标签: regex r if-statement


    【解决方案1】:

    要检查字符串是否包含某个子字符串,您不能使用==,因为它执行完全匹配(即仅当字符串完全为“非”时才返回真)。 例如,您可以使用执行模式匹配grepl函数(属于grep family of functions):

    df$loc01 <- ifelse(grepl("non",df$loc_01),'outside','inside')
    

    结果:

    > df
         loc_01 loc01_land   loc01
    1      apis  165730500  inside
    2      indu   62101800  inside
    3      isro  540687600  inside
    4      miss  161140500  inside
    5  non_apis 1694590200 outside
    6  non_indu 1459707300 outside
    7  non_isro 1025051400 outside
    8  non_miss 1419866100 outside
    9  non_piro 2037064500 outside
    10 non_sacn 2204629200 outside
    11 non_slbe 1918840500 outside
    12 non_voya  886299300 outside
    13     piro  264726000  inside
    14     sacn  321003900  inside
    15     slbe  241292700  inside
    16     voya  530532000  inside
    

    【讨论】:

    • @digEmAll 您如何将此解决方案扩展到要匹配的值列表?如果我想匹配“du”或“bis”或“lb”而不是“non”,那么如果 df$loc01 包含这些值中的任何一个,loc01 列将是“inside”,如果没有在匹配的 3 个中,loc01 列将是“外部”?
    • @user3614783:您可以使用更复杂的正则表达式,例如:grepl("du|bis|lb",df$loc_01)
    • 谢谢@digEmAll。我尝试将此应用于我的特定问题并收到警告消息“输入字符串 317 在此语言环境中无效”。根据您的示例,我的代码是: clean$SeriesReader
    • 您可能在您的语言环境不支持的 FavoriteSciFiFantasySeries 中有一些字符...您可以尝试遵循此线程中的建议:link
    【解决方案2】:

    你只需要一行代码:

    library(dplyr)
    library(stringr)
    
    
    df %>% 
      mutate(loc01 = if_else(str_starts(loc_01, "non_"), "outside", "inside"))
    

    要使用更复杂的正则表达式模式,您可以使用str_detect 而不是str_starts

    df %>% 
      mutate(loc01 = if_else(str_detect(loc_01, "^(non_)"), "outside", "inside"))
    

    输出:

       loc_01   loc01_land loc01  
       <chr>         <dbl> <chr>  
     1 apis      165730500 inside 
     2 indu       62101800 inside 
     3 isro      540687600 inside 
     4 miss      161140500 inside 
     5 non_apis 1694590200 outside
     6 non_indu 1459707300 outside
     7 non_isro 1025051400 outside
     8 non_miss 1419866100 outside
     9 non_piro 2037064500 outside
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-07
      • 2022-01-20
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      相关资源
      最近更新 更多