If else语句,其值是R中连续字符的一部分



我的数据帧(df(包含一个值列表,这些值按照"月份"、"站点名称"one_answers"相机编号"的格式进行标记。也就是说,如果我的值是"DECBUTCAM27",那么12月至12月,但是站点名称和CAM27相机编号

我有100个这样的值,有19个不同的网站名称。

我想写一个If else代码,这样只有网站名称才能被识别,并添加相应的数字。

我最初的想法是为所有100个值添加相应的数字,但由于如果其他值超过50个值就不起作用,我就不能使用该选项。

这是我为我尝试过的选项写的:

df <- df2 %>% mutate(Site_ID =
ifelse (CT_Name == 'DECBUTCAM27', "1",
ifelse (CT_Name == 'DECBUTCAM28', "1",
ifelse (CT_Name == 'DECI2NCAM01', "2",
ifelse (CT_Name == 'DECI2NCAM07', "2",
ifelse (CT_Name == 'DECI5CAM39', "3",
ifelse (CT_Name == 'DECI5CAM40', "3","NoVal"))))))) 

我正在寻找一个代码,这样只有"BUT"、"I2N"one_answers"I5"这些站点才能被识别,并添加相应的编号。

如有任何帮助,我们将不胜感激。

使用正则表达式提取站点名称,并使用match+unique分配唯一编号。

df2$site_name <- sub('...(.*)CAM.*', '\1', df2$CT_Name)
df2$Site_ID <- match(df2$site_name, unique(df2$site_name))

例如,请参阅以下示例:

CT_Name <- c('DECBUTCAM27', 'DECBUTCAM28', 'DECI2NCAM07', 'DECI2NCAM01', 
'DECI5CAM39', 'DECI5CAM40')
site_name <- sub('...(.*)CAM.*', '\1', CT_Name)
site_name
#[1] "BUT" "BUT" "I2N" "I2N" "I5"  "I5" 
Site_ID <- match(site_name, unique(site_name))
Site_ID
#[1] 1 1 2 2 3 3

这里有一个tidyverse解决方案:

  1. 您还没有提供可复制的示例,但让我们使用您提供的CT_Names来创建测试数据帧:
data <- tribble(
~ CT_Name,
"DECBUTCAM27",
"DECBUTCAM28",
"DECI2NCAM01",
"DECI2NCAM07",
"DECI5CAM39",
"DECI5CAM40"
)
  1. 假设字符串格式为3个字母表示月份,2个或更多字母或数字表示站点,CAM+1个或更多数字表示相机编号(根据需要调整(。我们可以在tidyrextract()函数中使用正则表达式将字符串拆分为其组件:
data_new <- data %>% 
extract(CT_Name, regex = "(\w{3})(\w{2,})(CAM\d+)", into = c("Month", "Site", "Camera"))

(如果要保留原始CT_Name变量,请添加remove = FALSE(

这产生:

# A tibble: 6 x 3
Month Site  Camera
<chr> <chr> <chr> 
1 DEC   BUT   CAM27 
2 DEC   BUT   CAM28 
3 DEC   I2N   CAM01 
4 DEC   I2N   CAM07 
5 DEC   I5    CAM39 
6 DEC   I5    CAM40
  1. 然后我们可以按站点分组,并将组ID分配为您的site_ID:
data_new <- data %>% 
extract(CT_Name, regex = "(\w{3})(\w{2,})(CAM\d+)", into = c("Month", "Site", "Camera")) %>%
group_by(Site) %>%
mutate(Site_ID = cur_group_id())

这产生:

# A tibble: 6 x 4
# Groups:   Site [3]
Month Site  Camera Site_ID
<chr> <chr> <chr>    <int>
1 DEC   BUT   CAM27        1
2 DEC   BUT   CAM28        1
3 DEC   I2N   CAM01        2
4 DEC   I2N   CAM07        2
5 DEC   I5    CAM39        3
6 DEC   I5    CAM40        3

这里有一个使用regex查找站点代码并使用apply函数返回代码向量的快速示例。

df <- data.frame(code = c('DECBUTCAM27','JANBUTCAM27','DECDUCCAM45'))
df$loc <- apply(df, 1, function(x) gsub("CAM.*$","",gsub("^.{3}",'',x[1])))
unique(df$loc) # all the location of the file
df$n <- as.numeric(as.factor(df$loc)) # get a number for each location

请注意,在这里我使用x[1],因为代码位于data.frame的第一列,这可能会因您而异。

---编辑——这是以前的答案,也有效,但还有更多的工作要做。但是,它允许你选择数字代码值(或文本(来分配位置,例如,如果它们是有序的。

它要求你为每个网站输入所有代码,我发现这在代码方面很重,但它很有效。开关部分与ifelse大致相同。

正则表达式包括排除"CAM"序列后面的3个第一个字符和其他字符。

df <- data.frame(code = c('DECBUTCAM27','JANBUTCAM27','DECDUCCAM45'))
df$n <- apply(df, 1, function(x) switch(gsub("CAM.*$","",gsub("^.{3}",'',x[1])),
BUT = 1,
DUC = 2)
)