Classify the Item_Number of the ‘Standard Tables of Food Composition in Japan 2010’

I have released ‘Standard Tables of Food Composition in Japan 2010′ on Jan. 18, 2012. However, I did not classify which Item_Number is categorized into food groups or derived from any organism.

In this contents, I have described incomplete way how to classify them.

Example 1 shows that the code exports Item_Number, major category, medium category, minor category and details. Please note that the tree structures is not complete.

Example 2 shows complete tree structures. However, I could not write the complete code with recursion.

Example 1. Incomplete data
Item Number Major Category Medium Category Minor Category Major Category Medium Category Minor Category
01012 こむぎ [玄穀] 国産 Wheat [Whole grain] Domestic
01013

輸入

Imported
01014

輸入

Imported
01015
[小麦粉] 薄力粉
[Wheat  flour] Soft flour
01016 
[小麦粉] 薄力粉
[Wheat flour] Soft flour
01018

中力粉

Medium flour
01019  
中力粉

Medium flour
01020

強力粉

Hard flour
01021

強力粉

Hard flour
01023 

強力粉

Hard flour
01024

プレミックス粉

Premixed flour
01025

プレミックス粉

Premixed flour
Example 2. Complete data
Item Number Major Category Medium Category Minor Category Major Category MediumCategory MinorCategory
01012 こむぎ [玄穀] 国産 Wheat [Whole grain] Domestic
01013 こむぎ [玄穀] 輸入 Wheat [Whole grain] Imported
01014 こむぎ [玄穀] 輸入 Wheat [Whole grain] Imported
01015 こむぎ [小麦粉] 薄力粉 Wheat [Wheat  flour] Soft flour
01016  こむぎ [小麦粉] 薄力粉 Wheat [Wheat flour] Soft flour
01018 こむぎ [小麦粉] 中力粉 Wheat [Wheat flour] Medium flour
01019  こむぎ [小麦粉] 中力粉 Wheat [Wheat flour] Medium flour
01020 こむぎ [小麦粉] 強力粉 Wheat [Whole flour] Hard flour
01021 こむぎ [小麦粉] 強力粉 Wheat [Wheat flour] Hard flour
01023 こむぎ [小麦粉] 強力粉 Wheat [Wheat flour] Hard flour
01024 こむぎ [小麦粉] プレミックス粉 Wheat [Wheat flour] Premixed flour
01025 こむぎ [小麦粉] プレミックス粉 Wheat [Wheat flour] Premixed flour

Please copy text from the PDF files and paste to EXCEL worksheet by such procedure as described in this content. Press ‘Alt’ key and ‘F11’ key to load VBE. Run the following code:

Option Explicit
Sub ItemNum()
Dim mySht           As Worksheet
Dim myRng           As Range
Dim i               As Long
Dim j               As Long
Dim k               As Long
Dim tmpAr           As Variant
Dim myItem()        As String
Dim myNum1()        As String
Dim myNum2()        As String
Dim ItemNumAr()     As String
Dim myCancel()      As String
Dim Cancel_Ar()     As String
Dim myAr()          As String
Dim myAr2()         As String
Dim myGroupNamJP()  As String
Dim myGroupNumJP()  As String
Dim myGroupNamEN()  As String
Dim myGroupNumEN()  As String
Dim GroupAr()       As String
Dim myRegExp1       As Object
Dim myRegExp2       As Object
Dim myStrPtn        As String
Dim myStrPtn2       As String
Const startStrPtn   As String = "^(1\\)|residues)$"
Dim tmpStrJ         As String
Dim tmpStrE         As String
Const endStrPtn     As String = "[0-9]\\)$"
Const JapStrPtn     As String = "([ぁ-ヶ]|[亜-黑])+$"
Dim myStr           As String
Set mySht = ActiveSheet
Set myRng = Application.Intersect(mySht.Range("A:F"), _
                                    mySht.UsedRange)
tmpAr = myRng
Set myRegExp1 = CreateObject("VBScript.RegExp")
myStrPtn = "^[0-9]{5}$"
With myRegExp1
    .Pattern = myStrPtn
    .IgnoreCase = True
    .Global = True
End With
Set myRegExp2 = CreateObject("VBScript.RegExp")
With myRegExp2
    .Pattern = startStrPtn
    .IgnoreCase = True
    .Global = True
End With
j = 0
For i = LBound(tmpAr) To UBound(tmpAr)
    If myRegExp1.Test(tmpAr(i, 1)) And _
       tmpAr(i, 2) <> "(欠番)" Then
        ReDim Preserve myItem(j)
        ReDim Preserve myNum1(j)
        myItem(j) = tmpAr(i, 1)
        myNum1(j) = i
    Else
        j = j - 1
    End If
    j = j + 1
Next i
ReDim ItemNumAr(j - 1, 2)
    ItemNumAr(LBound(ItemNumAr), 0) = myItem(LBound(ItemNumAr))
    ItemNumAr(LBound(ItemNumAr), 1) = 7
    ItemNumAr(LBound(ItemNumAr), 2) = myNum1(LBound(ItemNumAr))
For k = LBound(ItemNumAr) + 1 To UBound(ItemNumAr)
    ItemNumAr(k, 0) = myItem(k)
    ItemNumAr(k, 1) = myNum1(k - 1) + 1
    ItemNumAr(k, 2) = myNum1(k)
Next k
Erase myItem
Erase myNum1
j = 0
For i = LBound(tmpAr) To UBound(tmpAr)
    If myRegExp2.Test(tmpAr(i, 1)) _
    Then
        ReDim Preserve myItem(j)
        ReDim Preserve myNum1(i)
        myItem(j) = tmpAr(i, 1)
        myNum1(j) = i
    Else
        j = j - 1
    End If
    j = j + 1
Next i
ReDim myCancel(UBound(myItem), 1)
For k = LBound(myCancel) To UBound(myCancel)
    myCancel(k, 0) = myItem(k)
    myCancel(k, 1) = myNum1(k)
Next k
Erase myItem
Erase myNum1
ReDim Preserve myCancel(UBound(myCancel), 2)
j = 0
For i = LBound(myCancel) To UBound(myCancel) - 1
    If myCancel(i, 0) = "1)" Then
        If myCancel(i + 2, 0) = "residues" Then
            myCancel(i, 2) = myCancel(i + 2, 1)
        Else
            myCancel(i, 2) = myCancel(i + 1, 1)
        End If
    Else
        j = j - 1
    End If
    j = j + 1
Next i
ReDim Cancel_Ar(j - 1, 2)
j = 0
For i = LBound(myCancel) To UBound(myCancel) - 1
    If myCancel(i, 0) = "1)" Then
        Cancel_Ar(j, 0) = myCancel(i, 0)
        Cancel_Ar(j, 1) = myCancel(i, 1)
        Cancel_Ar(j, 2) = myCancel(i, 2)
    Else
        j = j - 1
    End If
    j = j + 1
Next i
k = 0
ReDim myItem(k)
ReDim myNum1(k)
ReDim myNum2(k)
For i = LBound(ItemNumAr) To UBound(ItemNumAr)
    ReDim Preserve myItem(k)
    ReDim Preserve myNum1(k)
    ReDim Preserve myNum2(k)
    For j = LBound(Cancel_Ar) To UBound(Cancel_Ar)
        If CLng(ItemNumAr(i, 1)) < CLng(Cancel_Ar(j, 1)) And _
                                   CLng(Cancel_Ar(j, 1)) < CLng(ItemNumAr(i, 2)) And _
           CLng(ItemNumAr(i, 1)) < CLng(Cancel_Ar(j, 2)) And _
                                   CLng(Cancel_Ar(j, 2)) < CLng(ItemNumAr(i, 2)) _
        Then
            If Cancel_Ar(j, 1) - ItemNumAr(i, 1) < 3 Then
                myItem(k) = ItemNumAr(i, 0)
                myNum1(k) = Cancel_Ar(j, 2)
                myNum2(k) = ItemNumAr(i, 2)
            Else
                myNum2(k) = Cancel_Ar(j, 1)
                k = k + 1
                ReDim Preserve myItem(k)
                ReDim Preserve myNum1(k)
                ReDim Preserve myNum2(k)
                myItem(k) = ItemNumAr(i, 0)
                myNum1(k) = Cancel_Ar(j, 2)
                myNum2(k) = ItemNumAr(i, 2)
            End If
        Else
            myItem(k) = ItemNumAr(i, 0)
            myNum1(k) = ItemNumAr(i, 1)
            myNum2(k) = ItemNumAr(i, 2)
        End If
    Next j
    k = k + 1
Next i
ReDim myAr(UBound(myItem), 2)
For i = LBound(myAr) To UBound(myAr)
    myAr(i, 0) = myItem(i)
    myAr(i, 1) = myNum1(i)
    myAr(i, 2) = myNum2(i)
Next i
Erase myItem
Erase myNum1
Erase myNum2
myStrPtn2 = "^(\\[|\\()?[a-zA-Z]+"
With myRegExp1
    .Pattern = myStrPtn2
    .IgnoreCase = True
    .Global = True
End With
k = 0
For i = LBound(tmpAr) To UBound(tmpAr)
    For j = LBound(myAr) To UBound(myAr)
        If CLng(myAr(j, 1)) < i And _
           CLng(myAr(j, 2)) > i And _
           myRegExp1.Test(tmpAr(i, 1)) _
        Then
            ReDim Preserve myGroupNamJP(k)
            ReDim Preserve myGroupNumJP(k)
            ReDim Preserve myGroupNamEN(k)
            ReDim Preserve myGroupNumEN(k)
            myGroupNamJP(k) = tmpAr(i - 1, 1) & _
                           tmpAr(i - 1, 2) & _
                           tmpAr(i - 1, 3) & _
                           tmpAr(i - 1, 4) & _
                           tmpAr(i - 1, 5) & _
                           tmpAr(i - 1, 6)
            myGroupNumJP(k) = i - 1
            myGroupNamEN(k) = RTrim(tmpAr(i, 1) & " " & _
                         Replace(tmpAr(i, 2), "*", "") & " " & _
                         Replace(tmpAr(i, 3), "*", "") & " " & _
                         Replace(tmpAr(i, 4), "*", "") & " " & _
                         Replace(tmpAr(i, 5), "*", "") & " " & _
                         Replace(tmpAr(i, 6), "*", ""))
            myGroupNumEN(k) = i
        Else
            k = k - 1
        End If
        k = k + 1
    Next j
Next i
ReDim GroupAr(UBound(myGroupNamJP), 3)
For i = LBound(GroupAr) To UBound(GroupAr)
    GroupAr(i, 0) = myGroupNamJP(i)
    GroupAr(i, 1) = myGroupNumJP(i)
    GroupAr(i, 2) = myGroupNamEN(i)
    GroupAr(i, 3) = myGroupNumEN(i)
Next i
Erase myGroupNamJP
Erase myGroupNumJP
Erase myGroupNamEN
Erase myGroupNumEN
k = 0
For i = LBound(GroupAr) To UBound(GroupAr)
    ReDim Preserve myGroupNamJP(k)
    ReDim Preserve myGroupNumJP(k)
    ReDim Preserve myGroupNamEN(k)
    ReDim Preserve myGroupNumEN(k)
    myGroupNamJP(k) = GroupAr(i, 0)
    myGroupNumJP(k) = GroupAr(i, 1)
    myGroupNamEN(k) = GroupAr(i, 2)
    myGroupNumEN(k) = GroupAr(i, 3)
    k = k + 1
    For j = LBound(Cancel_Ar) To UBound(Cancel_Ar)
        If CLng(Cancel_Ar(j, 1)) < CLng(GroupAr(i, 1)) And _
           CLng(GroupAr(i, 1)) < CLng(Cancel_Ar(j, 2)) _
        Then
            k = k - 1
        End If
    Next j
Next i
ReDim GroupAr(UBound(myGroupNamJP), 3)
With myRegExp1
    .Pattern = endStrPtn
    .IgnoreCase = True
    .Global = True
End With
With myRegExp2
    .Pattern = JapStrPtn
    .IgnoreCase = True
    .Global = True
End With
For i = LBound(GroupAr) To UBound(GroupAr)
    myGroupNamJP(i) = myRegExp1.Replace(myGroupNamJP(i), "")
    myGroupNamEN(i) = myRegExp1.Replace(myGroupNamEN(i), "")
    myGroupNamEN(i) = RTrim(myRegExp2.Replace(myGroupNamEN(i), ""))
    GroupAr(i, 0) = myGroupNamJP(i)
    GroupAr(i, 1) = myGroupNumJP(i)
    GroupAr(i, 2) = myGroupNamEN(i)
    GroupAr(i, 3) = myGroupNumEN(i)
Next i
ReDim Preserve myAr(UBound(myAr), 5)
ReDim myAr2(UBound(myAr), 3)
For i = LBound(myAr) To UBound(myAr)
    tmpStrJ = ""
    tmpStrE = ""
    myAr2(i, 0) = myAr(i, 0)
    For j = LBound(GroupAr) To UBound(GroupAr)
        If CLng(myAr(i, 1)) < CLng(GroupAr(j, 1)) And _
                              CLng(GroupAr(j, 3)) < CLng(myAr(i, 2)) Then
            tmpStrJ = tmpStrJ & GroupAr(j, 0)
            tmpStrE = RTrim(tmpStrE & " " & GroupAr(j, 2))
            myAr(i, 4) = GroupAr(j, 1)
        End If
    Next j
    If tmpStrJ = "" Then
        myAr(i, 3) = myAr(i - 1, 3)
        myAr(i, 4) = myAr(i - 1, 4)
        myAr(i, 5) = myAr(i - 1, 5)
        myAr2(i, 1) = myAr(i - 1, 3)
        myAr2(i, 2) = myAr(i - 1, 5)
    Else
        myAr(i, 3) = tmpStrJ
        myAr(i, 5) = tmpStrE
        myAr2(i, 1) = tmpStrJ
        myAr2(i, 2) = tmpStrE
    End If
Next i
Set mySht = Worksheets.Add
With mySht
    .Range("A1").Value = "Item_Number"
    .Range("B1").Value = "上位食品名(日)"
    .Range("C1").Value = "上位食品名(英)"
    .Range("A2:C450") = myAr2
End With
Erase ItemNumAr
Erase Cancel_Ar
Erase GroupAr
Erase myAr
Erase myAr2
Set mySht = Nothing
Set myRng = Nothing
Set myRegExp1 = Nothing
Set myRegExp2 = Nothing
End Sub

日本食品標準成分表2010の食品番号を分類する

日本食品標準成分表2010のテキストデータで日本食品標準成分表2010のテキストデータを公開しましたが,食品番号がどの食品群に属するか,どの生物由来かなどの分類ができていませんでした.今回は不十分ではありますが,食品番号を分類する方法を述べます.

注意点として例1に挙げたように,大分類・中分類・小分類・細目のツリー構造が完全ではありません.本来は例2のようであるべきですが,ツリー構造を解析するには再帰呼び出しによる構成展開が必要で,私の今のスキルでは無理でした.ご了承下さい.

例1.コードを実行して得られるデータ
Item Number Major Category Medium Category Minor Category Major Category Medium Category Minor Category
01012 こむぎ [玄穀] 国産 Wheat [Whole grain] Domestic
01013

輸入

Imported
01014

輸入

Imported
01015
[小麦粉] 薄力粉
[Wheat  flour] Soft flour
01016 
[小麦粉] 薄力粉
[Wheat flour] Soft flour
01018

中力粉

Medium flour
01019  
中力粉

Medium flour
01020

強力粉

Hard flour
01021

強力粉

Hard flour
01023 

強力粉

Hard flour
01024

プレミックス粉

Premixed flour
01025

プレミックス粉

Premixed flour
例2.必要なデータ
Item_Number Major Category Medium Category Minor Category Major Category MediumCategory MinorCategory
01012 こむぎ [玄穀] 国産 Wheat [Whole grain] Domestic
01013 こむぎ [玄穀] 輸入 Wheat [Whole grain] Imported
01014 こむぎ [玄穀] 輸入 Wheat [Whole grain] Imported
01015 こむぎ [小麦粉] 薄力粉 Wheat [Wheat  flour] Soft flour
01016  こむぎ [小麦粉] 薄力粉 Wheat [Wheat flour] Soft flour
01018 こむぎ [小麦粉] 中力粉 Wheat [Wheat flour] Medium flour
01019  こむぎ [小麦粉] 中力粉 Wheat [Wheat flour] Medium flour
01020 こむぎ [小麦粉] 強力粉 Wheat [Whole flour] Hard flour
01021 こむぎ [小麦粉] 強力粉 Wheat [Wheat flour] Hard flour
01023 こむぎ [小麦粉] 強力粉 Wheat [Wheat flour] Hard flour
01024 こむぎ [小麦粉] プレミックス粉 Wheat [Wheat flour] Premixed flour
01025 こむぎ [小麦粉] プレミックス粉 Wheat [Wheat flour] Premixed flour

PDFからテキスト情報を貼り付けるのはこのコンテンツに記載したのと同じ手順です.AltキーとF11キーを押下してVBEを起動し,標準モジュールに以下のコードを貼り付けて実行して下さい.

Option Explicit
Sub ItemNum()
Dim mySht           As Worksheet
Dim myRng           As Range
Dim i               As Long
Dim j               As Long
Dim k               As Long
Dim tmpAr           As Variant
Dim myItem()        As String
Dim myNum1()        As String
Dim myNum2()        As String
Dim ItemNumAr()     As String
Dim myCancel()      As String
Dim Cancel_Ar()     As String
Dim myAr()          As String
Dim myAr2()         As String
Dim myGroupNamJP()  As String
Dim myGroupNumJP()  As String
Dim myGroupNamEN()  As String
Dim myGroupNumEN()  As String
Dim GroupAr()       As String
Dim myRegExp1       As Object
Dim myRegExp2       As Object
Dim myStrPtn        As String
Dim myStrPtn2       As String
Const startStrPtn   As String = "^(1\\)|residues)$"
Dim tmpStrJ         As String
Dim tmpStrE         As String
Const endStrPtn     As String = "[0-9]\\)$"
Const JapStrPtn     As String = "([ぁ-ヶ]|[亜-黑])+$"
Dim myStr           As String
Set mySht = ActiveSheet
Set myRng = Application.Intersect(mySht.Range("A:F"), _
                                    mySht.UsedRange)
tmpAr = myRng
Set myRegExp1 = CreateObject("VBScript.RegExp")
myStrPtn = "^[0-9]{5}$"
With myRegExp1
    .Pattern = myStrPtn
    .IgnoreCase = True
    .Global = True
End With
Set myRegExp2 = CreateObject("VBScript.RegExp")
With myRegExp2
    .Pattern = startStrPtn
    .IgnoreCase = True
    .Global = True
End With
j = 0
For i = LBound(tmpAr) To UBound(tmpAr)
    If myRegExp1.Test(tmpAr(i, 1)) And _
       tmpAr(i, 2) <> "(欠番)" Then
        ReDim Preserve myItem(j)
        ReDim Preserve myNum1(j)
        myItem(j) = tmpAr(i, 1)
        myNum1(j) = i
    Else
        j = j - 1
    End If
    j = j + 1
Next i
ReDim ItemNumAr(j - 1, 2)
    ItemNumAr(LBound(ItemNumAr), 0) = myItem(LBound(ItemNumAr))
    ItemNumAr(LBound(ItemNumAr), 1) = 7
    ItemNumAr(LBound(ItemNumAr), 2) = myNum1(LBound(ItemNumAr))
For k = LBound(ItemNumAr) + 1 To UBound(ItemNumAr)
    ItemNumAr(k, 0) = myItem(k)
    ItemNumAr(k, 1) = myNum1(k - 1) + 1
    ItemNumAr(k, 2) = myNum1(k)
Next k
Erase myItem
Erase myNum1
j = 0
For i = LBound(tmpAr) To UBound(tmpAr)
    If myRegExp2.Test(tmpAr(i, 1)) _
    Then
        ReDim Preserve myItem(j)
        ReDim Preserve myNum1(i)
        myItem(j) = tmpAr(i, 1)
        myNum1(j) = i
    Else
        j = j - 1
    End If
    j = j + 1
Next i
ReDim myCancel(UBound(myItem), 1)
For k = LBound(myCancel) To UBound(myCancel)
    myCancel(k, 0) = myItem(k)
    myCancel(k, 1) = myNum1(k)
Next k
Erase myItem
Erase myNum1
ReDim Preserve myCancel(UBound(myCancel), 2)
j = 0
For i = LBound(myCancel) To UBound(myCancel) - 1
    If myCancel(i, 0) = "1)" Then
        If myCancel(i + 2, 0) = "residues" Then
            myCancel(i, 2) = myCancel(i + 2, 1)
        Else
            myCancel(i, 2) = myCancel(i + 1, 1)
        End If
    Else
        j = j - 1
    End If
    j = j + 1
Next i
ReDim Cancel_Ar(j - 1, 2)
j = 0
For i = LBound(myCancel) To UBound(myCancel) - 1
    If myCancel(i, 0) = "1)" Then
        Cancel_Ar(j, 0) = myCancel(i, 0)
        Cancel_Ar(j, 1) = myCancel(i, 1)
        Cancel_Ar(j, 2) = myCancel(i, 2)
    Else
        j = j - 1
    End If
    j = j + 1
Next i
k = 0
ReDim myItem(k)
ReDim myNum1(k)
ReDim myNum2(k)
For i = LBound(ItemNumAr) To UBound(ItemNumAr)
    ReDim Preserve myItem(k)
    ReDim Preserve myNum1(k)
    ReDim Preserve myNum2(k)
    For j = LBound(Cancel_Ar) To UBound(Cancel_Ar)
        If CLng(ItemNumAr(i, 1)) < CLng(Cancel_Ar(j, 1)) And _
                                   CLng(Cancel_Ar(j, 1)) < CLng(ItemNumAr(i, 2)) And _
           CLng(ItemNumAr(i, 1)) < CLng(Cancel_Ar(j, 2)) And _
                                   CLng(Cancel_Ar(j, 2)) < CLng(ItemNumAr(i, 2)) _
        Then
            If Cancel_Ar(j, 1) - ItemNumAr(i, 1) < 3 Then
                myItem(k) = ItemNumAr(i, 0)
                myNum1(k) = Cancel_Ar(j, 2)
                myNum2(k) = ItemNumAr(i, 2)
            Else
                myNum2(k) = Cancel_Ar(j, 1)
                k = k + 1
                ReDim Preserve myItem(k)
                ReDim Preserve myNum1(k)
                ReDim Preserve myNum2(k)
                myItem(k) = ItemNumAr(i, 0)
                myNum1(k) = Cancel_Ar(j, 2)
                myNum2(k) = ItemNumAr(i, 2)
            End If
        Else
            myItem(k) = ItemNumAr(i, 0)
            myNum1(k) = ItemNumAr(i, 1)
            myNum2(k) = ItemNumAr(i, 2)
        End If
    Next j
    k = k + 1
Next i
ReDim myAr(UBound(myItem), 2)
For i = LBound(myAr) To UBound(myAr)
    myAr(i, 0) = myItem(i)
    myAr(i, 1) = myNum1(i)
    myAr(i, 2) = myNum2(i)
Next i
Erase myItem
Erase myNum1
Erase myNum2
myStrPtn2 = "^(\\[|\\()?[a-zA-Z]+"
With myRegExp1
    .Pattern = myStrPtn2
    .IgnoreCase = True
    .Global = True
End With
k = 0
For i = LBound(tmpAr) To UBound(tmpAr)
    For j = LBound(myAr) To UBound(myAr)
        If CLng(myAr(j, 1)) < i And _
           CLng(myAr(j, 2)) > i And _
           myRegExp1.Test(tmpAr(i, 1)) _
        Then
            ReDim Preserve myGroupNamJP(k)
            ReDim Preserve myGroupNumJP(k)
            ReDim Preserve myGroupNamEN(k)
            ReDim Preserve myGroupNumEN(k)
            myGroupNamJP(k) = tmpAr(i - 1, 1) & _
                           tmpAr(i - 1, 2) & _
                           tmpAr(i - 1, 3) & _
                           tmpAr(i - 1, 4) & _
                           tmpAr(i - 1, 5) & _
                           tmpAr(i - 1, 6)
            myGroupNumJP(k) = i - 1
            myGroupNamEN(k) = RTrim(tmpAr(i, 1) & " " & _
                         Replace(tmpAr(i, 2), "*", "") & " " & _
                         Replace(tmpAr(i, 3), "*", "") & " " & _
                         Replace(tmpAr(i, 4), "*", "") & " " & _
                         Replace(tmpAr(i, 5), "*", "") & " " & _
                         Replace(tmpAr(i, 6), "*", ""))
            myGroupNumEN(k) = i
        Else
            k = k - 1
        End If
        k = k + 1
    Next j
Next i
ReDim GroupAr(UBound(myGroupNamJP), 3)
For i = LBound(GroupAr) To UBound(GroupAr)
    GroupAr(i, 0) = myGroupNamJP(i)
    GroupAr(i, 1) = myGroupNumJP(i)
    GroupAr(i, 2) = myGroupNamEN(i)
    GroupAr(i, 3) = myGroupNumEN(i)
Next i
Erase myGroupNamJP
Erase myGroupNumJP
Erase myGroupNamEN
Erase myGroupNumEN
k = 0
For i = LBound(GroupAr) To UBound(GroupAr)
    ReDim Preserve myGroupNamJP(k)
    ReDim Preserve myGroupNumJP(k)
    ReDim Preserve myGroupNamEN(k)
    ReDim Preserve myGroupNumEN(k)
    myGroupNamJP(k) = GroupAr(i, 0)
    myGroupNumJP(k) = GroupAr(i, 1)
    myGroupNamEN(k) = GroupAr(i, 2)
    myGroupNumEN(k) = GroupAr(i, 3)
    k = k + 1
    For j = LBound(Cancel_Ar) To UBound(Cancel_Ar)
        If CLng(Cancel_Ar(j, 1)) < CLng(GroupAr(i, 1)) And _
           CLng(GroupAr(i, 1)) < CLng(Cancel_Ar(j, 2)) _
        Then
            k = k - 1
        End If
    Next j
Next i
ReDim GroupAr(UBound(myGroupNamJP), 3)
With myRegExp1
    .Pattern = endStrPtn
    .IgnoreCase = True
    .Global = True
End With
With myRegExp2
    .Pattern = JapStrPtn
    .IgnoreCase = True
    .Global = True
End With
For i = LBound(GroupAr) To UBound(GroupAr)
    myGroupNamJP(i) = myRegExp1.Replace(myGroupNamJP(i), "")
    myGroupNamEN(i) = myRegExp1.Replace(myGroupNamEN(i), "")
    myGroupNamEN(i) = RTrim(myRegExp2.Replace(myGroupNamEN(i), ""))
    GroupAr(i, 0) = myGroupNamJP(i)
    GroupAr(i, 1) = myGroupNumJP(i)
    GroupAr(i, 2) = myGroupNamEN(i)
    GroupAr(i, 3) = myGroupNumEN(i)
Next i
ReDim Preserve myAr(UBound(myAr), 5)
ReDim myAr2(UBound(myAr), 3)
For i = LBound(myAr) To UBound(myAr)
    tmpStrJ = ""
    tmpStrE = ""
    myAr2(i, 0) = myAr(i, 0)
    For j = LBound(GroupAr) To UBound(GroupAr)
        If CLng(myAr(i, 1)) < CLng(GroupAr(j, 1)) And _
                              CLng(GroupAr(j, 3)) < CLng(myAr(i, 2)) Then
            tmpStrJ = tmpStrJ & GroupAr(j, 0)
            tmpStrE = RTrim(tmpStrE & " " & GroupAr(j, 2))
            myAr(i, 4) = GroupAr(j, 1)
        End If
    Next j
    If tmpStrJ = "" Then
        myAr(i, 3) = myAr(i - 1, 3)
        myAr(i, 4) = myAr(i - 1, 4)
        myAr(i, 5) = myAr(i - 1, 5)
        myAr2(i, 1) = myAr(i - 1, 3)
        myAr2(i, 2) = myAr(i - 1, 5)
    Else
        myAr(i, 3) = tmpStrJ
        myAr(i, 5) = tmpStrE
        myAr2(i, 1) = tmpStrJ
        myAr2(i, 2) = tmpStrE
    End If
Next i
Set mySht = Worksheets.Add
With mySht
    .Range("A1").Value = "Item_Number"
    .Range("B1").Value = "上位食品名(日)"
    .Range("C1").Value = "上位食品名(英)"
    .Range("A2:C450") = myAr2
End With
Erase ItemNumAr
Erase Cancel_Ar
Erase GroupAr
Erase myAr
Erase myAr2
Set mySht = Nothing
Set myRng = Nothing
Set myRegExp1 = Nothing
Set myRegExp2 = Nothing
End Sub

How to change the number of the first element of two-dimensional dynamic array in EXCEL VBA?

EXCEL VBA restricts two-dimensional dynamic array to change the number of element in the last dimension only. Although the constraint, what could you do when you would like to change the first dimension of two-dimensional dynamic array? Please see the code below;

Option Explicit
Sub DynamicArray_Sample()
Dim mySht   As Worksheet
Dim myRng   As Range
Dim tmpAr   As Variant
Dim myAr()  As String
Dim myID()  As String
Dim myStr() As String
Dim i       As Long
Set mySht = Worksheets.Add
With mySht
    .Range("A1").Value = "10001"
    .Range("A2").Value = "10002"
    .Range("A3").Value = "10003"
    .Range("A4").Value = "10004"
    .Range("A5").Value = "10005"
    .Range("B1").Value = "aaaaa"
    .Range("B2").Value = "bbbbb"
    .Range("B3").Value = "ccccc"
    .Range("B4").Value = "ddddd"
    .Range("B5").Value = "eeeee"
End With
Set myRng = mySht.UsedRange
tmpAr = myRng
For i = LBound(tmpAr) To UBound(tmpAr)
    ReDim Preserve myID(i)
    ReDim Preserve myStr(i)
    myID(i) = myAr(i, 0)
    myStr(i) = myAr(i, 1)
Next i
ReDim Preserve myID(UBound(myID) + 1)
ReDim Preserve myStr(UBound(myStr) + 1)
myID(UBound(myID)) = "10006"
myStr(UBound(myStr)) = "fffff"
ReDim myAr(UBound(myID), 1)
For i = LBound(myAr) To UBound(myAr)
    myAr(i, 0) = myID(i)
    myAr(i, 1) = myStr(i)
Next i
Set mySht = Worksheets.Add
With mySht
    .Range("A1:B6") = myAr
End With
Set mySht = Nothing
End Sub

EXCEL VBA で2次元動的配列の第1次元の要素数を変更する

EXCEL VBAでの2次元動的配列には最終次元,つまり第2次元の要素数の変更しかできないという制約があります.しかし現実問題として第1次元の要素数を変更したいという需要はあります.今回は2次元動的配列の第1次元の要素数の変更方法を述べます.下記のコードで2次元配列の全要素を一旦1次元動的配列に書き出し,1次元配列の要素数を増やしてから再度2次元配列に書き戻しています.

Option Explicit
Sub DynamicArray_Sample()
Dim mySht   As Worksheet
Dim myRng   As Range
Dim tmpAr   As Variant
Dim myAr()  As String
Dim myID()  As String
Dim myStr() As String
Dim i       As Long
Set mySht = Worksheets.Add
With mySht
    .Range("A1").Value = "10001"
    .Range("A2").Value = "10002"
    .Range("A3").Value = "10003"
    .Range("A4").Value = "10004"
    .Range("A5").Value = "10005"
    .Range("B1").Value = "aaaaa"
    .Range("B2").Value = "bbbbb"
    .Range("B3").Value = "ccccc"
    .Range("B4").Value = "ddddd"
    .Range("B5").Value = "eeeee"
End With
Set myRng = mySht.UsedRange
tmpAr = myRng
For i = LBound(tmpAr) To UBound(tmpAr)
    ReDim Preserve myID(i)
    ReDim Preserve myStr(i)
    myID(i) = myAr(i, 0)
    myStr(i) = myAr(i, 1)
Next i
ReDim Preserve myID(UBound(myID) + 1)
ReDim Preserve myStr(UBound(myStr) + 1)
myID(UBound(myID)) = "10006"
myStr(UBound(myStr)) = "fffff"
ReDim myAr(UBound(myID), 1)
For i = LBound(myAr) To UBound(myAr)
    myAr(i, 0) = myID(i)
    myAr(i, 1) = myStr(i)
Next i
Set mySht = Worksheets.Add
With mySht
    .Range("A1:B6") = myAr
End With
Set mySht = Nothing
End Sub

The text file, ‘Standard Tables of Food Composition in Japan 2010’

I requested Office for Resources Policy Division Science and Technology Policy
Bureau, Ministry of Education, Culture, Sports, Science and Technology (MEXT) to approve that I publish the text file, ‘Standard Tables of Food Composition in Japan 2010’ at the end of 2011. On January 13, 2012, I have received the e-mail from staff that the settlement has been completed. Therefore, I have published the text file, ‘Standard Tables of Food Composition in Japan 2010’. Please note the following:

1. I have replaced the strings ‘(0)’, ‘Tr’, ‘(Tr)’ and ‘-‘ with ‘0’.

2. The text file is derived from ‘Standard Tables of Food Composition in Japan 2010’, published by Report of the Subdivision on Resources The Council for Science and Technology, MEXT, JAPAN. Please contact MEXT to obtain application or notification before duplication or reproduction.

E-mail: kagseis@mext.go.jp

M_FOODS

Reference:
CSV file of the ‘Standard Tables of Food Composition in Japan 2010′

日本食品標準成分表2010のテキストデータ

文部科学省科学技術・学術政策局政策課資源室に表題のファイルの公開を申請しておりましたが,1月13日決裁が終了したとの連絡がありましたので,公開いたします.なお,公開したファイルを利用するにあたっては下記の2点についてご注意下さい.

1.「日本食品標準成分表2010」に記載されている,(0),Tr,(Tr),-,について,当データでは「 0 」と表記しています.

2.本表の食品成分値は文部科学省科学技術・学術審議会資源調査分科会報告「日本食品標準成分表2010」によるものです.食品成分値を複製又は転載する場合は事前に文部科学省への許可申請もしくは届け出が必要となる場合があります.

連絡先:文部科学省科学技術・学術政策局政策課資源室 E-mail: kagseis@mext.go.jp

M_FOODS.csv

決裁にあたり,各項目の名称と単位とを付記されたいとの依頼が電話でありました.後日修正してアップロードします.

参照:
日本食品標準成分表2010のcsvファイル

Simplified nutritional screening tools for patients on maintenance hemodialysis

I read the paper below, which describes that MIS is best criteria for assessment of nutrition status of hemodialysis patients. But the method is time-consuming and needs skill. The GNRI is most simple method using only serum albumin, height and body weight for assessment them.

Simplified nutritional screening tools for patients on maintenance hemodialysis

Kohsuke Yamada, Ryuichi Furuya, Takako Takita, Yukitaka Maruyama, Yuri Yamaguchi, Sakae Ohkawa and Hiromichi Kumagai

1 From the Department of Clinical Nutrition, School of Food and Nutritional Sciences and the COE Program in the 21st Century, University of Shizuoka, Shizuoka, Japan (KY, YY, SO, and HK); the Renal Division, Department of Internal Medicine, Iwata City Hospital, Iwata, Shizuoka, Japan (RF); and the Maruyama Hospital, Hamamatsu, Japan (TT and YM)

Background:

Malnutrition is a prevalent complication in patients on maintenance hemodialysis. Nutritional screening tools may be useful to identify those patients at nutritional risk from among hundreds of hemodialysis patients in a large facility.

Objective:

We tested several simplified nutritional screening tools on hemodialysis patients to validate the potential application of the tools.

Design:

The simplified nutritional screening tools were chosen from references published between 1985 and 2005. Nutritional assessments, including history taking, and anthropometric and biochemical measurements were performed on 422 hemodialysis patients. These results were applied to obtain the score of each nutritional screening tool and the malnutrition-inflammation score (MIS), a comprehensive nutritional assessment tool, as the reference standard. The usefulness of each nutritional screening tool for identifying nutritional risk was assessed by comparison with the MIS value and various individual nutritional measures.

Results:

Five reliable nutritional screening tools were found by the literature search. Among them, the geriatric nutritional risk index (GNRI) was considered to be the most accurate in identifying hemodialysis patients at nutritional risk, because the area under the receiver operating characteristic curve generated with the MIS value was the largest. The GNRI showed a significantly negative correlation with the MIS (r = –0.67, P < 0.0001), and the most accurate GNRI cutoff to identify a malnourished patient according to the MIS was <91.2. The GNRI's sensitivity, specificity, and accuracy of <91.2 in predicting malnutrition according to the MIS were 0.730, 0.819, and 0.787, respectively.

Conclusion:

The GNRI was the simplest and most accurate risk index for identifying hemodialysis patients at nutritional risk according to the MIS.

Key Words:

Geriatric nutritional risk index • hemodialysis • nutritional assessment • nutritional screening • malnutrition-inflammation score • nutritional risk

維持透析患者のための簡易栄養スクリーニングツール

 最近読んだ論文の内容が良かったので,リンク先と全文の日本語訳を掲載します.MIS という栄養評価のためのゴールデンスタンダードのツールがあるんですが,手間暇かかるのでもっと簡単なツールを幾つか比べてみたら,結局アルブミンと身長と体重だけから計算した GNRI というツールが一番良かった,というのが荒筋です.なお,日本語訳は不完全な箇所があるかもしれませんが,その責任は私にあります.Simplified nutritional screening tools for patients on maintenance hemodialysis



以下和訳です.

維持透析患者のための簡易栄養スクリーニングツール

Kohsuke Yamada, Ryuichi Furuya, Takako Takita, Yukitaka Maruyama, Yuri Yamaguchi, Sakae Ohkawa and Hiromichi Kumagai
1 From the Department of Clinical Nutrition, School of Food and Nutritional Sciences and the COE Program in the 21st Century, University of Shizuoka, Shizuoka, Japan (KY, YY, SO, and HK); the Renal Division, Department of Internal Medicine, Iwata City Hospital, Iwata, Shizuoka, Japan (RF); and the Maruyama Hospital, Hamamatsu, Japan (TT and YM)

要約

背景

 低栄養は維持透析患者においては一般的な合併症である.多くの施設において膨大な数の透析患者から栄養リスクのある患者を同定するために栄養スクリーニングツールは有用と思われる.

対象

 我々は透析患者に対する幾つかの簡易栄養ツールを実行し,ツールの潜在的有用性を検証した.

デザイン

 簡易栄養スクリーニングツールは1985年から2005年に刊行された参考文献から選択した.病歴を含めた栄養評価と身体所見,生化学検査を422名の透析患者に施行した.これらの結果は各栄養評価ツール及びmalnutrition-inflammation score (MIS) の点数化に用いた.MISは標準として参照される総合的栄養評価ツールである.栄養リスクを同定する各種栄養スクリーニングツールの有用性はMIS値および様々な個々の栄養指標と比較して評価した.

結果

 5つの信頼性の高い栄養スクリーニングツールが文献検索により判明した.そのうちgeriatric nutritional screening index (GNRI高齢者栄養指標) が最も正確に透析患者の栄養リスクを同定できると考えられた.MIS値により生成したAUCが最大だったからである.GNRIはMIS値と著明な負の相関 (r = – 0.67, P < 0.0001) を認め,MIS値で低栄養を識別する最も正確なGNRIのカットオフ値は91.2未満であった.MISにより低栄養を識別した患者のうち,GNRIが91.2未満の感度,特異度,精度はそれぞれ0.730, 0.819, 0.787であった.

結論

 GNRIはMISによる透析患者の低栄養リスクを同定する最も簡素で最も正確なリスク指標である.

Am J Clin Nutr 2008;87:106-113

KEY WORDS

Geriatric nutritional risk index, hemodialysis, nutritional assessment, nutritional screening, malnutrition-inflammation score, nutritional risk

導入

 蛋白エネルギー低栄養は透析を受けている患者では一般的に見られる合併症である.蛋白エネルギー低栄養は予後不良と相関し,栄養管理は維持透析患者において重要な治療アプローチと考えられているからである.栄養管理において栄養評価は必須かつ初歩の臨床的処置であり,Dialysis Outcome Quality Initiative (DOQI) ガイドラインでは全ての透析患者に対する定期的な栄養評価を推奨している.信頼性の高い栄養状態の評価には学術的な手順,身体測定,生化学検査,運動耐容能,栄養評価,主観的評価が必要である.しかしそれらの手順のほとんどは熟練した栄養士が施行する時でさえ時間がかかり,手間がかかるものである.

 栄養スクリーニングは低栄養リスクのある患者を同定する実用的な代替手段である.一般的な目的と高齢者や小児,入院患者や地域の患者,老人ホームの高齢者,癌患者やHIV感染者,嚥下困難の患者など特定の患者のために,多くの栄養スクリーニングツールが発達してきた.それらのうち,subjective global assessment (SGA) は栄養リスクをスクリーニングするために検証されてきた臨床的なツールである.このツールは病歴と臨床所見に基づいており,今や多くの施設で用いられている.SGAは慢性腎不全患者においても他の栄養スクリーニングツールからの参照基準として用いられてきた.Kalantar-Zadeh らはmalnutrition-inflammation score (MIS) を開発した.それはSGAと7つの要素を共有しており, SGAとは異なる3つの要素を追加している.それはbody mass index (BMI), 血清アルブミン,TIBCである.MISはSGAより優れた栄養指標と検証され,維持透析患者及び腹膜透析患者の両者に対する有用な栄養評価ツール足りうる.しかしながらMISもSGAも評価者による主観的評価を要するため,異なる評価者と異なる評価時において一貫性のある結果を確保するには高度の訓練を要する.

 一方,これらのより簡易な栄養スクリーニングツールはきちんと定義された規則かカットオフ値により点数化されている.これらのツールは一般的な身体計測を用いるもので,大多数の人口に迅速に適用できる.それらのツールとは Mini Nutritional Assessment-Short Form (MNA-SF), nutritional risk score (NRS), Malnutrition Universal Screening Tool (MUST), Malnutrition Screening Tool (MST), geriatric nutritional risk index (GNRI) である.それらは2つから5つの要素からなり,高齢者や入院患者に用いるために開発された.これらの栄養スクリーニングツールは一つ以上の研究によって検証されたにも関わらず,透析患者を用いた報告がなかった.本研究ではこれらの簡易栄養スクリーニングツールをMISおよび個々の維持透析患者の栄養計測と比較し検証する.

対象と方法

対象

 対象は朝夕予定の維持透析患者から募集した.患者は静岡市の磐田市立病院と浜松市の丸山病院に通院する外来透析患者である.この研究の選択基準は6ヶ月以上安定して維持透析を続けていることと,心血管疾患や消化管疾患,呼吸器疾患,精神疾患,進行性の低栄養など重篤な合併症のないことである.寝たきり患者は除外した.理由は身体活動の欠如のため筋萎縮に陥っているからである.最終的に422名(男性275名,女性147名)の患者を登録した.平均年齢は63.8±12.1歳で平均透析期間は11.9±8.8年間であった.糖尿病罹患率は全患者の16.3%であった.血液透析は週に3回施行し,一回あたり4.1±0.4時間かかり,ホローファイバーダイアライザー(中空糸透析膜)と重炭酸緩衝液でエンドトキシンフリー透析液(キンダリーAF3P)を使用した.血流速度は 213.6 ± 38.2 ml/分(160から300ml/minの範囲)で透析液流量は 500 ml/min であった.患者は既に栄養士からの教育を終えており,塩分,カリウム,水分,エネルギーは 35 kcal/kg/day, 蛋白質は 1.2 g/kg/day となるよう指導されたが,実際のエネルギーと蛋白質摂取は基本的に任意とした.

 すべての患者から書面でインフォームドコンセントを得た.本研究のプロトコールは磐田市立病院及び丸山病院,静岡大学の倫理委員会によって承認された.

栄養評価とスクリーニングツール

 Table1 に示すように,我々はMISと他の幾つかの簡易栄養スクリーニングツールを評価した.それらは1985年から2005年までに刊行された文献から選択し,2つ以上の独立した研究班によって適切な方法で施行されたものである.これらの参考文献はすべてPubMedデータベースから抽出した.栄養評価は2005年の4月から7月にかけて全患者に実施した.病歴,身体所見,身体計測,血液検査を同じ週に患者ごとに実施した.これらのデータを様々な栄養評価ツールに適用した.低栄養のカットオフ値は大元の研究であるMISで定義されたもののみ使用した.

Malnutrition-Inflammation score

 MIS はKalantar-Zadehらにより開発されたもので,原法又は変法SGAの7つの要素および3つの付加的要素,つまりBMI,血清アルブミン値,TIBCからなる.従来のSGAの要素は病歴と身体所見の両者により点数化される.病歴は5つの要素で構成される.過去6ヶ月間での体重減少,消化器症状,食事摂取量,運動耐容能,透析期間を含む合併症である.身体所見は2つの要素から構成される.皮下脂肪の欠如と筋萎縮である.細胞外液量は透析の間限外濾過により本質的に管理されているため,浮腫や腹水といったSGA原法の3つ目の要素の出現は維持透析患者において栄養指標になりえない.MIS の各々の要素は重症度に応じて0(正常)から3(非常に重症)までの4つのレベルを持つ.全部で10個の要素の合計は0(正常)から30(非常に低栄養)までの範囲である.低栄養のカットオフ値は6と定義されている.低栄養の患者のほとんどがこれで同定されるからである.

Mini Nutritional Assessment-Short Form

 MNA-SF は高齢者の低栄養を検出するために European Society of Parenteral and Enteral Nutrition guideline により推奨されている.MNA には2つの手順がある.MNA-SF は低栄養のスクリーニングに用いられ,full MNA は栄養状態の評価に用いられる.本研究においては MNA-SF を栄養スクリーニングに用いた.MNA-SF は6つの要素からなる.3ヶ月以上の食事摂取減少(0-2),過去3ヶ月間の体重減少(0-3),可動性(0-2),過去3ヶ月間の精神的ストレスまたは急性疾患(0-2),精神神経学的問題(0-2),BMI(0-3)である.合計点数は0から14である.

Nutrition risk score

 NRS はReillyらにより入院患者のために開発された.5つの要素からなり,過去3ヶ月間の意図せぬ体重減少,BMI,食欲,食物を摂取するか保持するかのいずれかあるいは両者の能力,臨床的または医学的あるいはその両者のストレス因子である.それぞれの要素は0から3に点数化され,合計は0から15点の範囲である.

Malnutrition Universal Screening Tool

 成人の MUST は Malnutrition Advisory Group of British Association for Parenteral and Enteral Nutrition によって学問的に使用するために開発された.MUST は独立した3つの要素からなる.BMIを測定した現在の体重の状態(0-2),意図せぬ体重減少(0-2),5日を超えて栄養学的摂取の全くない状態に至る急性疾患の影響(0-2).これらの点数の合計を計算する.

Malnutrition Screening Tool

 MST は Ferguson らにより開発され,急性の入院患者に用いられ,3つの要素からなる.体重減少(0-2),体重減少の量(1-4),経口摂取減少か食欲不振(0-1).合計点数を患者ごとに計算する.

Geriatric nutritional risk index

 GNRI はnutritional risk index (NRI) を高齢者向けに修飾したものである.このインデックスは血清アルブミン値と体重からなり以下の式で計算される.

\displaystyle GNRI=1.489 \times albumin (g/L) + 41.7 \times \frac{body weight}{ideal body weight}\quad(1)

 体重の理想体重比は,患者の体重が理想体重を超える場合は1に設定する.本研究においては,理想体重は身長とBMIを22として計算した値と定義した.BMI22の妥当性のゆえにオリジナルの GNRI の式で用いられる Lorentz 式で計算された値を用いなかった.我々は GNRI 点数を両者の式で比較したが,ほとんど差異は認められなかった.(Figure 1)

身体測定

 透析ごとに前後の体重を測定し,透析後の体重を理想体重として用いた.BMIは理想体重を用いて計算した.シャントのない腕の上腕周囲長 (MAC) と上腕三頭筋皮下脂肪厚 (TSF) をHarpenden 皮下脂肪キャリパーで計測した.

 上腕筋面積 (MAMA) は以下の式で計算した.

\displaystyle MAMA=\frac{(MAC-31.4 \times TSF)^2}{12.56}\quad(2)

 MAMA, MAC, TSF はセンチメートル単位で計測した.

身体組成の計測

 大腿部の筋肉の面積はX線CTを用いて測定した.大腿部の短軸CT像は膝蓋骨上縁から大腿骨の大転子に伸びる線の中点で得た.患者は仰臥位で大腿筋を伸展させて検査した.スライス厚は10mmだった.放射線画像はデジタルスキャンしてPCで解析した.除脂肪大腿筋面積 (TMA) と大腿骨面積 (TBA) はNIH IMAGE で定量化した.これはアメリカNIH の Wayne Rasband が開発したパブリックドメインの面積測定プログラムである. TBA で標準化されたTMA (例えば TMA の TBA に対する比である TMA/TBA など) は筋肉量の指標であり,体格や年齢,性別で調整する必要がない.透析患者において TMA/TBA が10未満であることは低栄養状態と考えられる.体脂肪率は周波数50kHzで50μアンペアの生体電気インピーダンス解析により得られ,タニタのBC-552を用いた.

検査室の手順

 血清アルブミン,クレアチニン,尿素窒素,総コレステロール,中性脂肪,TIBC,ヘマトクリット,リンパ球数を自動計測器による標準的検査手順を用いて測定した.血清プレアルブミンと高感度CRPはレーザー比濁法により定量した.透析量は以下の式で求めた.

\displaystyle Kt/V_{urea}=-\ln(R-0.008 \times t)+(4-(3.5 \times R)) \times \frac{UF}{W}\quad(3)

 Kt/V は単一プール Kt/V であり,R は透析後の透析前に対する血清窒素の比であり,t (hour) は透析時間であり,UF (L) は限外濾過量であり,W (kg) は透析後体重である.食事蛋白摂取量の測定は標準化蛋白窒素出現率(nPNA) で標準化した.これはK/DOQI Hemodialysis Adequacy Working Groupにより刊行された式で計算する.

\displaystyle nPNA (g/kg/day)=\frac{C_0}{36.3+5.48(Kt/V)+53.5/(Kt/V)}+0.168\quad(4)

 C0 (mg/dL) は透析前の血清尿素窒素濃度である.このデータは本研究期間中の週の始めごとに集められて用いた.

統計解析

 それぞれの変数は平均値±標準偏差として表現した.群間の差異は分散分析又はノンパラメトリック検定で評価した.それらは傾斜分布とそれに続くボンフェローニ法を持つデータであった.単回帰解析も用いて変数間の相関を調べた.P値0.05未満を統計学的有意とみなした.

 MIS を参考基準とすることで各々の栄養スクリーニングツールの ROC 曲線を生成した.AUC は栄養上のリスクを判別する確率を示した.それぞれのツールの栄養のカットオフ値は ROC 曲線の最大感度から(1 – 特異度)を差し引いた値で求めた.分割表を作成して各栄養スクリーニングツールとそれぞれの栄養に関する変数又は MIS との間で相関を解析した.これらの表は感度,特異度,正確度,陽性的中率 (PPV),陰性的中率 (NPV) をそれぞれ以下の式によって定義して作成した.

\displaystyle Sensitivity = \frac{true positives}{true positives + false negatives}\quad(5)\vspace{0.2in}\\  Specificity = \frac{true negatives}{true negatives + false positives}\quad(6)\vspace{0.2in}\\  Accuracy = \frac{true positives + true negatives}{total numbers}\qquad(7)\vspace{0.2in}\\  PPV = \frac{true test positives}{all test positives}\quad(8)\vspace{0.2in}\\  NPV = \frac{true test negatives}{all test negatives}\quad(9)

検査後確率を定義するため,陽性尤度比 (LR+) と陰性尤度比 (LR-) を以下の式で計算した.

\displaystyle LR+ = \frac{sensitivity}{1 - specificity}\quad(10)\vspace{0.2in}\\  LR- = \frac{1 - sensitivity}{specificity}\quad(11)

すべての透析解析はGB-STAT および JMP にて行った.

結果

 患者は MIS 点数により3群に分類された.正常栄養群(0-5点),軽度低栄養群(6-10点),中等度から重度低栄養群(11点以上)(Table 2).個々の栄養指標のほとんどは身体所見と生化学検査を含んでおり,MIS 値の高い群ではMIS 値の低い群に比較して有意に栄養指標が低かった(P < 0.05).さらに CRP のように栄養に関連する指標でさえ高 MIS 群では低 MIS 群よりも高かった.これらの結果は MIS を本研究における参照基準として評価することが合理的と考えられることを示している.

 本研究では各種の栄養スクリーニングツールの点数を MIS の3群と比較した(Table 3).これらすべての点数は MIS の高低群間で著明に差が見られた(P < 0.0001).しかしながらこれらのツール間では低栄養を識別する能力は異なった.MIS値6点以上として定義される低栄養では,ROC AUC はGNRI が最大であり,降順に NRS, MNA-SF, MUST, 最後に MST であった(Figure 2).この結果は GNRI が栄養リスクを識別する最も優れたツールであることを示唆している.

 栄養リスクを識別する最も正確なカットオフ値はこれらのROC AUC に由来する(Figure 2).これらのカットオフ値は様々な生化学検査や身体所見の指標の異常値から各栄養スクリーニングツールの感度,特異度,正確度 の計算に用いられる(Table 4).GNRI はこれらのスクリーニングツールの中で低アルブミン血症に最も高い感度,特異度,正確度 を示した.GNRI はまた他の臨床的栄養指標にも高い診断価値を示した.

 GNRI は MIS に対して著明な負の相関を示した(r = – 0.67, P < 0.0001; Figure 3).MISに基づく低栄養の GNRI 値は 91.2 未満で感度,特異度,正確度 の値はそれぞれ0.730, 0.819, 0.787 であった.PPV (0.717) と NPV (0.787) もまた高い点数を示した.GNRI に基づく低栄養のリスクのある患者における検査後確率は尤度比で求められた.GNRI に対する LR+ と LR- はそれぞれ 4.03, 0.330 であった.これは MIS が GNRI による栄養リスクの診断にほとんど変化をもたらさないことを示唆している.本研究において維持透析患者に GNRI を適用することで,GNRI が91.2より大きいか91.2以下であるかでは,種々の栄養関連指標に著明な差がある(P < 0.05)ことがわかった(Table 5).

考察

 毎年世界中で多くの透析患者が増加しているにもかかわらず,患者の増加に見合うだけの栄養士のような健康に関わる職種の人数は増えていない.その結果栄養士一人あたりの透析患者数は増え続けている.1995年には34.9名であったのが2005年には50.3名となった.日本においては83%の栄養士がパートタイム勤務である.フルタイム相当で勤務する各栄養士あたりの透析患者数の平均人数は米国での124名に相当し,英国の128名に相当すると報告されている.腎臓治療チームにおける栄養士の人数が限られているという問題に直面し,大規模施設における何百名もの維持透析患者の中から栄養リスクにある患者を同定するのに,栄養スクリーニングツールは極めて重要となってきた.

 我々は簡易栄養スクリーニングツールの有用性を確認する参考基準としてMIS を使用した.MIS は総合的栄養評価ツールであり,Kalantar-Zadeh らによって開発され,維持透析患者において低栄養と炎症を評価するのに実際的で測定に再現性がある.それは SGA に基づいた定量的栄養評価であり,SGA ではないいくつかの客観的要素,つまり BMI,血清アルブミン値,TIBC を含んでいる.MIS 値は透析患者において罹患率,死亡率,種々の栄養に関する変数,例えば炎症,貧血,エリスロポエチン抵抗性などと相関すると報告されている.Table 2 に示すように,我々は高 MIS 値は多くの個々の栄養計測の劣化と相関することも見出した.それゆえ我々は MIS は栄養スクリーニングツールを評価する参考基準として最も合理的な選択であると確信している.

 MIS が参考基準として使われるときには GNRI は低栄養を予測する最も正確なスクリーニングツールであると考えられる.GNRI は非常にシンプルな式で計算され,血清アルブミン,身長,体重のたった3つの変数しか持たない.この栄養点数は客観的情報のみからなり,それゆえ評価者によるいかなる主観的判断も排除できる.さらにはこの式はコンピュータにより処理できるため,多くの中から低栄養の高リスク患者を呼び出しうる.

 Buzby らにより記述された NRI によると,GNRI は栄養リスクのある高齢の入院患者を同定するために Bouillanne らによって開発された.NRI は若い術後の患者のリスクを点数化するものである.GNRI は高齢入院患者において,栄養関連の罹患率および死亡率について信頼できる予後の指標であると報告されている.GNRI の数式は血清アルブミンと体重減少を含み,高齢患者及び維持透析患者の死亡率に対してはどちらも強い独立危険因子である.

 MIS に基づいて低栄養のリスクを評価する種々の栄養スクリーニングツール間で ROC AUC を比較すると,GNRI の正確度が最も高かった.GNRI はまた本研究においてカットオフ値を 91.2 に用いたときに,維持透析患者の低アルブミン血症と低筋肉量 (TMA/TBA) のリスクを評価するのに最も高い正確度を有していた.GNRI が 91.2 未満であることは MIS 値に基づく低栄養を予測するのに高い感度,特異度,陽性的中率,陰性的中率を示した.さらに,尤度比は検査後確率が検査前確率と比べて殆ど差がないことを示唆している.これらの統計解析の結果は GNRI が栄養リスクにある低栄養透析患者をスクリーニングするのに十分に高い信頼性を有することを示唆している.

 GNRI のカットオフ値は本研究では ROC AUC から 91.2 と定義された.Bouillanne により定義されたオリジナルの 98 より低い.それは栄養リスクの違いを反映している.Bouillanne による定義では高齢の低栄養患者とはアルブミン値 3.8 g/dL, 理想体重の 95 % とされているが,一方維持透析患者においてはアルブミン 3.5 g/dL, BMI 18.5 が用いられているためである.

 カットオフ値は本研究において ROC AUC の最大感度から (1 – 特異度) を差し引いた値と定義した.この点は感度の最大値と(1 – 特異度)の最小値が最も良いカットオフ値であることを意味している.もし栄養スクリーニングツールがスクリーニングだけに用いられ,もしそれがもっと詳細な栄養評価をサポートしていたなら,栄養リスクを検出するのにもっと高いカットオフ値を設定することさえ可能であった.この処理は高い感度が得られるにもかかわらず,特異度も高い.しかしながら GNRI のカットオフ値に 91.2 を用いる時に PPV および NPV の検査後確率が高い値を示している.これはそれ以上の評価は不要であろうことを示唆している.

 GNRI と比較すると他の簡易栄養スクリーニングツールは,MIS による低栄養を予測する ROC AUC からは,あまり正確でないように見える.一つの可能性として,食欲や経口摂取量,精神的ストレスといった曖昧さがスクリーニングに組み込まれているということがあるのかもしれない.これらの計測値を点数化することは不正確な主訴に依存しており,検査者の手腕に依存している.他の理由としてこれらの研究に用いられた患者の人数が挙げられるかもしれない.殆どの栄養スクリーニングは入院患者や術後の患者,または高齢者のために開発されたものである.GNRI もまた高齢者のために開発されたものであるにもかかわらず,GNRI の2つの要素(血清アルブミンとBMI)は透析患者の罹患率と死亡率によく相関することが証明された.さらに,これらの要素は透析患者における栄養,炎症,貧血の側面の代表値であることも明らかになった.それゆえ,GNRI が透析患者における最も正確な栄養スクリーニングツールとして登場することは驚くには当たらない.

 本研究の限界はこれらの栄養スクリーニングツールを基本的なリスクである罹患率や死亡率について直接十分に検証出来なかった点である.一つの客観的栄養スクリーニングは栄養リスクがあり,臨床的予後に高いリスクを有する患者を同定することである.本研究の結果以下のことが示唆された.維持透析患者の将来の入院と死亡と相関することが知られている MIS と共に,GNRI は最大の正確度をもつ.この事実は GNRI が患者の予後を規定することを意味している.しかしながら,維持透析患者における栄養スクリーニングツールとしての GNRI の意義を確立するには,更に大規模な縦断的研究が必要であろう.
結論として,本研究は GNRI が最も簡易で,かつ数ある栄養スクリーニングツールの中でも MIS による低栄養の維持透析患者を同定するには最も正確なリスク指標たりうることを示した.GNRI を導入することで,透析患者の栄養評価の効率性と合理化が改善するであろう.