如何替换列名中第二次或多次出现的点

How to replace second or more occurrences of a dot from a column name

伙计们,我如何替换列名中第二次出现的点?

示例数据:

age.range.abc = sample(c("ar2-15", "ar16-29", "ar30-44"), 200, replace = TRUE)
gender.region.q = sample(c("M", "F"), 200, replace = TRUE)
region_g.a = sample(c("A", "B", "C"), 200, replace = TRUE)
physi = sample(c("Poor", "Average", "Good"), 200, replace = TRUE)
survey = data.frame(age.range.abc, gender.region.q, region_g.a,physi)
head(survey)

我试过了,但它删除了所有带下划线的点。我只想用下划线替换第二次或多次出现。

names(survey) = gsub("\.", "_", names(survey))
names(survey)
# [1] "age_range_abc"   "gender_region_q" "region_g_a"      "physi" 

谢谢, J

一个选项是strsplit

names(survey) <- sapply(strsplit(names(survey), "[.]"), function(x) 
    if(length(x) >1) paste(x[1], paste(x[-1], collapse="_"), sep=".") else x)
names(survey)
#[1] "age.range_abc"   "gender.region_q" "region_g.a"      "physi"  

本着您原始代码的精神:

names(survey) = sub("(\..*?)\.", "\1_", names(survey))
names(survey)
[1] "age.range_abc"   "gender.region_q" "region_g.a"      "physi" 

一些额外的细节以备不时之需。

\. 匹配第一个 .
.*? . 匹配任何字符。 .* 匹配任何字符的零个或多个实例。但是匹配是贪心的;它会尽可能匹配。我想要不贪婪的匹配(直到第二个.)所以我添加了?抑制贪婪匹配和 .*? 匹配任何字符组,直到我们命中正则表达式中的下一个东西...
另一个 \. 来匹配第二个 ..
因为第一部分包含在括号 (\..*?) 中,它存储为 \1,所以替换模式 \1_ 恢复第二个 . 之前的所有内容,第二个 . 被替换为_ .

您可以将 sub(\.[^.]*)\. 一起使用,其中

\. 匹配 .

[^.] 匹配所有内容,但不匹配 .

* 匹配 0 次或更多次

中括号( )用来存放匹配,这里在\1:

sub("(\.[^.]*)\.", "\1_", names(survey))
#[1] "age.range_abc"   "gender.region_q" "region_g.a"      "physi"          

更明确地说,可以在第一个 ^ 表示字符串开头的地方使用 ^([^.]*\.[^.]*)\.

sub("^([^.]*\.[^.]*)\.", "\1_", names(survey))
#[1] "age.range_abc"   "gender.region_q" "region_g.a"      "physi"