私のデータには2つの異なるデータフレームが含まれています。
visits <- data.frame("visit_nr", "label", "degree", "code")
category <- data.frame("label", "degree", "group", "code1", "code2, "code3")
2つのデータフレーム間の「ラベル」、「度」、「コード」の一致に基づいて、データフレーム「訪問」のすべての訪問にグループを割り当てたいと思います。ただし、特定の「visit_nr」の行は、データフレーム「category」の「code2」と「code3」もデータフレーム「visits」にリストされている場合にのみ、特定のグループに割り当てることができます。つまり、行を特定のグループに割り当てるには、同じ「visit_nr」を持つ3つの行が必要です。ここで「label」は次のようになります。「度」と「コード」は次のいずれかに一致します。
- "label", "degree", "code1"
- "label", "degree", "code2"
- "label", "degree", "code3"
これらのデータフレームには両方とも50000を超える行が含まれているため、これを実現するためにループを使用することは避けたいと思います。
訪問
visit_nr | label | degree | code | Group
1601704801 | 171 | 1 | 354373 | 0
1601704801 | 171 | 1 | 200200 | 0
1601704801 | 171 | 1 | 973443 | 0
1601704801 | 171 | 1 | 475985 | 0
1601704801 | 171 | 1 | 994320 | 0
カテゴリー
label | degree | group | code1 | code2 | code3
171 | 1 | 2 | 354373| 200200| 475985
171 | 1 | 3 | 354373| 200200| 998282
171 | 1 | 1 | 354373| 200200| 0
期待される出力:
visit_nr | label | degree | code | Group
1601704801 | 171 | 1 | 354373 | 2
1601704801 | 171 | 1 | 200200 | 2
1601704801 | 171 | 1 | 973443 | 2
1601704801 | 171 | 1 | 475985 | 2
1601704801 | 171 | 1 | 994320 | 2
category
ワイドフォーマットからロングフォーマットに再形成し、結合してvisits
、一致するコードの数をカウントする代替アプローチがあります。
library(data.table)
# reshape from wide to long format
lcat <- melt(setDT(category), measure.vars = patterns("^code"),
value.name = "code")
# join and count
tmp <- lcat[setDT(visits), on = .(label, degree, code), nomatch = 0L][
, .N, by = .(visit_nr, label, degree, group)][
N == 3L]
tmp[]
visit_nr label degree group N 1: 1601704801 171 1 2 3
# update join
visits[tmp, on = .(visit_nr, label, degree), Group := group, mult = "first"][]
visits[]
visit_nr label degree code Group 1: 1601704801 171 1 354373 2 2: 1601704801 171 1 200200 2 3: 1601704801 171 1 973443 2 4: 1601704801 171 1 475985 2 5: 1601704801 171 1 994320 2
コメント、OPがあることが開示されています
列
code2
とcode3
データフレームのすべての行にcategory
値があるわけではありません。またcode1
、0とは異なる値のみcode2
をcode3
持ち、値が0である場合もあります。この場合visit_nr
、一致するグループを全体に割り当てるには、最初のコードのみが特定の範囲内に存在する必要があります。visit_nr
したがって、正確に3つの一致するコードがあるかどうかの簡単なチェックは、サンプルデータセットでは機能しますが、OPの本番データセットでは機能しません。
追加の要件は、次の2つの変更でカバーできると思います。
code == 0
がから削除されますlong
tmp
複数の一致が含まれている場合は、最も高いものN
が選択されます。同点がある場合which.max()
は、最初に遭遇したものを選択します。したがって、コードは次のようになります。
library(data.table)
lcat <- melt(setDT(category), measure.vars = patterns("^code"),
value.name = "code")[code != 0]
tmp <- lcat[setDT(visits), on = .(label, degree, code), nomatch = 0L][
, .N, by = .(visit_nr, label, degree, group)][
, .SD[which.max(N)], by = .(visit_nr, label, degree)]
visits[tmp, on = .(visit_nr, label, degree), Group := group]
visits[]
visit_nr label degree code Group 1: 1601704801 171 1 354373 2 2: 1601704801 171 1 200200 2 3: 1601704801 171 1 973443 2 4: 1601704801 171 1 475985 2 5: 1601704801 171 1 994320 2
library(data.table)
visits <- fread("
visit_nr | label | degree | code | Group
1601704801 | 171 | 1 | 354373 | 0
1601704801 | 171 | 1 | 200200 | 0
1601704801 | 171 | 1 | 973443 | 0
1601704801 | 171 | 1 | 475985 | 0
1601704801 | 171 | 1 | 994320 | 0
")
category <- fread("
label | degree | group | code1 | code2 | code3
171 | 1 | 2 | 354373| 200200| 475985
171 | 1 | 3 | 354373| 200200| 998282
171 | 1 | 1 | 354373| 200200| 0
")
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加