0

現在、R を使用して次の形式のテーブルデータを変換しています。

ID    Code    Condition    WT
104   KEENTRAN  CON4      .30577
.     .         .          .
.     .         .          .

リンクは、私のデータフレームをダウンロードしたい人なら誰でも機能するはずです。それ以外の場合は、サブセットを次に示します。

>dput(head(df))

structure(list(ID = c(104L, 368L, 10632L, 20385L, 24361L, 34378L
), Code = c("KEENTRAN", "ALEXEXPR", "MINNEXPMN", "JACKMOVWI", 
            "FREICOIN", "JBXEXPGA"), Condition = c("CON4", "CON4", "CON2", 
                                                   "CON2", "CON6", "CON5"), WT = c(0.3057717456, 0.7909870604, 1, 
                                                                                   1, 0.4301040524, 0.5977268575)), .Names = c("ID", "Code", "Condition", 
                                                                                                                               "WT"), class = c("tbl_df", "data.frame"), row.names = c(NA, -6L
                                                                                                                               ))

バックグラウンド

サンプル データは、Condition 変数の範囲が "CON1" から "CON6" までの長い形式になっています。IDCodeの値が主キーになり、Conditionのレベルが列になるワイド形式にデータを再キャストしたいと考えています。値は、その特定の ID、コード、条件グループ (または、そのようなペアが存在しない場合はゼロ)のWTの最大値を取ります。これは、パッケージのdcast()関数を使用して R で簡単に実現できます。reshape2

library(reshape2)

Result <- df %>% group_by(ID, Condition) %>% 
  summarise(value = max(as.numeric(WT))) %>% 
  dcast(ID ~ Condition)

Result[is.na(Result)] <- 0

このデータ操作手順を SQL Server で複製したいと考えていますが、最適な方法がわかりません。どんな助けや洞察も大歓迎です。

4

2 に答える 2

1

SQL Server のPIVOT操作を検討してください。

SELECT t.ID, 
       ISNULL(t.[CON1], 0) AS [CON1],
       ISNULL(t.[CON2], 0) AS [CON2],
       ISNULL(t.[CON3], 0) AS [CON3],
       ISNULL(t.[CON4], 0) AS [CON4],
       ISNULL(t.[CON5], 0) AS [CON5],
       ISNULL(t.[CON6], 0) AS [CON6]    
FROM RDataFrame As r                  
PIVOT 
  (
    MAX(r.[WT]) 
    FOR r.Condition IN ([CON1], [CON2], [CON3], [CON4], [CON5], [CON6])
  ) AS t

-- ID   CON1    CON2    CON3    CON4            CON5    CON6
-- 8    0       0       0       0.4394051665    0       0
-- 10   0       0       0       0.6013843825    0       0
-- 15   0       0       0       0.07231002554   0       0
-- 21   0       0       0       0.6013843825    0       0
-- 23   0       0       0       0.7720454793    0       0
-- 80   0       1       0       0               0       0
-- 104  0       0       0       0.3057717456    0       0
-- 144  0       0       0       0.1430937996    0       0.2646439667
-- 145  0       0       0       0.8276574       0       0
-- 155  0       1       0       0.8977280575    0       0
-- 156  0       0       0       0.8453629338    0       0
-- 158  0       0       0       0.5221399019    0       0
于 2016-10-29T04:50:34.963 に答える
0

SQL Server 2016 で次のことを行うことで、質問に答えることができました。

最初に、ポストされたデータ (ストアド プロシージャの結果) を一時テーブルにダンプしました。

DROP TABLE IF EXISTS #InputDataFrame
CREATE TABLE #InputDataFrame ( ID int, Code varchar(25), Condition varchar(25), WT float)
INSERT INTO #InputDataFrame
exec dbo.[Stored_Proc_to_Create_Sample_Data]   -- stored proc to create my posted data

次に、次のように目的の変換を再作成できました。

DROP TABLE IF EXISTS #DistinctIDs
CREATE TABLE #DistinctIDs ( ID int, Code varchar(25) )
INSERT INTO #DistinctIDs ( ID, Code)
Select Distinct
I.ID,
I.Code
From #InputDataFrame I

Select
D.*,
CASE WHEN CON1.WT IS NULL THEN 0 ELSE CON1.WT END as CON1,
CASE WHEN CON2.WT IS NULL THEN 0 ELSE CON2.WT END as CON2,
CASE WHEN CON3.WT IS NULL THEN 0 ELSE CON3.WT END as CON3,
CASE WHEN CON4.WT IS NULL THEN 0 ELSE CON4.WT END as CON4,
CASE WHEN CON5.WT IS NULL THEN 0 ELSE CON5.WT END as CON5,
CASE WHEN CON6.WT IS NULL THEN 0 ELSE CON6.WT END as CON6

From #DistinctIDs D

Left Join ( Select I.ID, MAX( I.WT) as WT From #InputDataFrame I Where I.Condition = 'CON1' Group By I.ID) CON1 on CON1.ID = D.ID
Left Join ( Select I.ID, MAX( I.WT) as WT From #InputDataFrame I Where I.Condition = 'CON2' Group By I.ID) CON2 on CON2.ID = D.ID
Left Join ( Select I.ID, MAX( I.WT) as WT From #InputDataFrame I Where I.Condition = 'CON3' Group By I.ID) CON3 on CON3.ID = D.ID
Left Join ( Select I.ID, MAX( I.WT) as WT From #InputDataFrame I Where I.Condition = 'CON4' Group By I.ID) CON4 on CON4.ID = D.ID
Left Join ( Select I.ID, MAX( I.WT) as WT From #InputDataFrame I Where I.Condition = 'CON5' Group By I.ID) CON5 on CON5.ID = D.ID
Left Join ( Select I.ID, MAX( I.WT) as WT From #InputDataFrame I Where I.Condition = 'CON6' Group By I.ID) CON6 on CON6.ID = D.ID

これが最もエレガントなソリューションであるとは思えませんが、私の目的には合ってい dcast()ました。設定で R の機能を模倣するのに苦労している可能性のある他の人に役立つことを願っていSQLます。

于 2016-10-28T21:36:32.857 に答える