◆ 基本は name 属性が同じものが同じグループ
◆ fieldset を分けても同じ name 属性だと同じグループ扱いになる
◆ form を分けると別グループにできる
  ◆ ラジオボタンのグループのために form をわけると form の機能で submit する使い方だと辛い時もある
◆ 同じ名前で fieldset ごとに別グループにしたいというときは 繰り返しになるということだと思うのでコンポーネント化して ShadowDOM を使えばいい
  ◆ ShadowDOM ごとに別グループになる

HTML ではラジオボタンのグループをつくるときに name 属性を指定します
同じ名前のものが同じグループです

<section>
<div>
<label><input type="radio" name="xx"> a</label>
<label><input type="radio" name="xx"> b</label>
</div>
<div>
<label><input type="radio" name="yy"> c</label>
<label><input type="radio" name="yy"> d</label>
<label><input type="radio" name="yy"> e</label>
</div>
</section>

こういう感じなのですが この section が複数あって選択項目も同じなのでコピペしたいときがあります
そのときに name は変えないようにしたいです
フォームをグループ化するためには fieldset というタグがあるので 使ってみましたが

<fieldset>
<input type="radio" name="r">
<input type="radio" name="r">
<input type="radio" name="r">
</fieldset>

<fieldset>
<input type="radio" name="r">
<input type="radio" name="r">
<input type="radio" name="r">
</fieldset>

これの上のグループとしたのグループが別々になりません
上側をチェックしたら下側のチェックが外れます
同じグループ扱いになってます

MDN 探してみるとラジオボタンのグループらしいタグがあったのですが Firefox 拡張機能用みたいで HTML では動きません
内部で name 管理して内側のグループ化する CustomElement でも作って対処しようと考えていたのですが form タグを使えば別々にできました

<form>
<input type="radio" name="r">
<input type="radio" name="r">
<input type="radio" name="r">
</form>

<form>
<input type="radio" name="r">
<input type="radio" name="r">
<input type="radio" name="r">
</form>

これなら上下両方にチェックを付けられます

私の場合基本 JavaScript で処理してそのまま送信するので form タグは基本使いません
なので グループ化のためだけに form 使うのは特に抵抗ないのですが form タグをちゃんと使ってる場合はネストすることになります
そう考えると name 変えずにグループ化したいなら CustomElement 作っておくほうがいいかもしれません

radio-group

form でできると気づく前に一応作ってたのはこんなのです

customElements.define(
"radio-item",
class extends HTMLElement {
constructor() {
super()

new MutationObserver(mutations => {
for (const mu of mutations) {
this.dispatchEvent(new Event("mutated", { bubbles: true }))
}
}).observe(this, {
subtree: true,
childList: true,
attributes: true,
attributeFilter: ["value"],
characterData: true,
})
}

get value() {
return this.getAttribute("value") || this.textContent
}

set value(value) {
this.setAttribute("value", value)
}
}
)

customElements.define(
"radio-group",
class extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: "open" }).innerHTML = `
<style></style>
<div id="radios"></div>
`

const radios = this.shadowRoot.querySelector("#radios")
const wmap = new WeakMap()

const prevRi = from => {
const prev = from.previousElementSibling
if (!prev) return null
if (prev.localName === "radio-item") return prev
return prevRi(prev)
}

const add = elem => {
const label = this._create(elem.textContent, elem.value)
const prev_ri = prevRi(elem)
if (prev_ri) {
const prev_label = wmap.get(prev_ri)
if (prev_label) {
prev_label.after(label)
} else {
radios.append(label)
}
} else {
radios.prepend(label)
}
wmap.set(elem, label)
}

const remove = elem => {
const label = wmap.get(elem)
if (label) {
label.remove()
wmap.delete(elem)
}
}

const change = elem => {
const label = wmap.get(elem)
if (label) {
const new_label = this._create(elem.textContent, elem.value, !!label.querySelector(":checked"))
label.replaceWith(new_label)
wmap.set(elem, new_label)
}
}

for (const elem of this.children) {
if (elem.localName === "radio-item") {
add(elem)
}
}

new MutationObserver(mutations => {
for (const mu of mutations) {
for (const elem of mu.addedNodes) {
if (elem.localName === "radio-item") {
add(elem)
}
}
for (const elem of mu.removedNodes) {
if (elem.localName === "radio-item") {
remove(elem)
}
}
}
}).observe(this, {
childList: true,
})

this.addEventListener("mutated", eve => {
if (eve.target.localName === "radio-item") {
change(eve.target)
}
})
}

_create(text, value, checked) {
const label = document.createElement("label")
label.innerHTML = `
<input type="radio" name="name" value="${value}" ${checked ? "checked" : ""}>
${text}
`
return label
}

get value() {
const elem = this.shadowRoot.querySelector(":checked")
return elem ? elem.value : null
}

set value(value) {
for (const checkbox of this.shadowRoot.querySelectorAll("input")) {
if (checkbox.value === value) {
checkbox.checked = true
return true
}
}
return false
}
}
)

使うときはこういう感じで name すらなくて radio-item にラベルのテキストを入れるだけです

<radio-group>
<radio-item>one</radio-item>
<radio-item>two</radio-item>
<radio-item>three</radio-item>
</radio-group>

<radio-group>
<radio-item>one</radio-item>
<radio-item>two</radio-item>
<radio-item>three</radio-item>
</radio-group>

MutationObserver が付いてるのでラベル名の切り替えや radio-item の追加削除に連動して ラジオボタンも変わります

DEMO

ShadowDOM でグループ化できた

作っていて気づいたのですが ShadowDOM で切り離されるとグループも別になります
もともとは radio-item ごとに ShadowDOM をアタッチしてそれぞれに input タグを入れていました
すると同じ name なのに全部に同時にチェックをつけることができてしまいました

その対処で radio-item に ShadowDOM をアタッチしないようにする作りにしたのですが 単純に 上で書いた例で言う section 単位でコンポーネント化してしまえば特に何もしなくてよかった気がします
コピペで繰り返す form パーツのセットならコンポーネント化してしまうのはありですし そうすれば普通の input タグで radio を指定するだけで済みます