У меня есть таблица Excel с данными, организованными таким образом, что каждая строка является образцом, а каждый столбец имеет другое свойство этого образца. Однако мне нужно реорганизовать его, чтобы он работал с GraphPad Prism.
В настоящее время данные организованы следующим образом:
И я хочу сделать график в виде прямоугольника и усов, показывающий оценку каждого уровня воздействия, например:
Мне нужно сделать это, включая все образцы, а затем еще раз только для препарата А и только для препарата Б.
Однако, чтобы сделать это в Prism, насколько мне известно, каждая комбинация переменных, которую вы хотите, должна иметь свой собственный столбец, например:
Это было бы достаточно легко сделать вручную, если бы был только один столбец результатов, но их двадцать два, так что я бы предпочел этого не делать. Есть ли какой-то автоматизированный способ реорганизации таблицы данных?
@RonRosenfeld Спасибо, я изменил таблицы на Markdown! Что касается результатов, это просто графики двух Score 1
чисел, у которых Exposure Level
равно 1, и Score 1
чисел, у которых Exposure Level
равно 2, и Score 1
чисел, у которых Exposure Level
равно 3.
Чтобы создать диаграмму Box & Whiskers, похожую на то, что вы показываете,
просто используйте уровень экспозиции для оси x и столбец Score 1 для оси y
Чтобы создать таблицу, похожую на показанные вами результаты, вы можете использовать Power Query.
Я создал ее как единую таблицу, где каждая строка представляет лекарство. Затем вы можете отфильтровать его по препарату для получения конкретных результатов.
MCode прокомментирован, поэтому, читая комментарии, а также глядя на окно Applied Steps, я надеюсь, что понял, что происходит.
Большая часть MCode генерируется из пользовательского интерфейса, но особенно шаги colNames
и ExpandTableColumns
ближе к концу вводятся вручную. В противном случае количество столбцов в расширении не будет гибким.
MCode
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
//Won't need ID column so get rid of it
#"Removed Columns2" = Table.RemoveColumns(Source,{"Sample ID"}),
//Unpivot the Score columns to put them in a single column
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Removed Columns2", {"Exposure Level", "Drug"}, "Attribute", "Value"),
//sort by Score, Attribute, Drug so the results will be properly ordered
#"Sorted Rows" = Table.Sort(#"Unpivoted Columns",{{"Attribute", Order.Ascending}, {"Exposure Level", Order.Ascending}, {"Drug", Order.Ascending}}),
//Create what will become a two line header column
// and remove the originals
#"Added Custom" = Table.AddColumn(#"Sorted Rows", "Headers", each "Exposure " & Text.From([Exposure Level]) & "#(lf)" & [Attribute]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Exposure Level", "Attribute"}),
//Move headers to first column
#"Reordered Columns" = Table.ReorderColumns(#"Removed Columns",{"Headers", "Drug", "Value"}),
//Group by Drug
#"Grouped Rows" = Table.Group(#"Reordered Columns", {"Drug"}, {{"Grouped", each _, type table [Headers=text, Drug=text, Value=number]}}),
//Add an Index column
#"Added Index" = Table.AddIndexColumn(#"Grouped Rows", "Index", 0, 1, Int64.Type),
/*From each grouped table, remove Drug Column
and remove Header column EXCEPT fromk the first table
then Transpose each grouped table*/
#"Added Custom1" = Table.AddColumn(#"Added Index", "Custom", each
Table.Transpose(
if [Index] = 0 then
Table.RemoveColumns([Grouped],"Drug")
else
Table.RemoveColumns([Grouped],{"Headers","Drug"}))),
//Remove no longer needed Grouped and Index columns
#"Removed Columns1" = Table.RemoveColumns(#"Added Custom1",{"Grouped", "Index"}),
//Expand the table columns, promote headers, and rename the drug column to get final results
colNames = Table.ColumnNames(#"Removed Columns1"[Custom]{0}),
#"Expanded Custom" = Table.ExpandTableColumn(#"Removed Columns1", "Custom", colNames),
#"Promoted Headers" = Table.PromoteHeaders(#"Expanded Custom", [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"A", type text}, {"Exposure 1#(lf)Score 1", type number}, {"Exposure 2#(lf)Score 1", type number}, {"Exposure 3#(lf)Score 1", type number}, {"Exposure 1#(lf)Score 22", type number}, {"Exposure 2#(lf)Score 22", type number}, {"Exposure 3#(lf)Score 22", type number}}),
#"Renamed Columns" = Table.RenameColumns(#"Changed Type",{{"A", "Drug"}})
in
#"Renamed Columns"
@ user3316549 прокомментировал ниже, что у него может быть несколько записей для одного и того же препарата для одного и того же Score/Exposure
, и хотел, чтобы результаты для каждого были показаны отдельно.
Здесь была бы полезна сводная таблица, за исключением того, что классическая сводная таблица будет иметь только одну запись для каждого пересечения Drug
с Score/Exposure
.
Эта проблема решается с помощью пользовательской функции сводной таблицы, которая при необходимости добавляет дополнительную строку. Кредиты для этой функции включены, и вы можете изучить ссылку для подробного объяснения алгоритма, используемого для этой части кода.
Пользовательская функция добавляется как blank query
. Вы можете назвать его так, как вы выберете, и назвать его таким образом в своем основном коде.
М-код
Основной запрос
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
//Unpivot the Score columns to put them in a single column
#"Unpivoted Columns" = Table.UnpivotOtherColumns(Source, {"Sample ID","Exposure Level", "Drug"}, "Attribute", "Value"),
//sort by multiple columns so the results will be properly ordered to our liking
#"Sorted Rows" = Table.Sort(#"Unpivoted Columns",{{"Attribute", Order.Ascending}, {"Exposure Level", Order.Ascending}, {"Drug", Order.Ascending},{"Sample ID", Order.Ascending}}),
//Create what will become a two line header column
// and remove the originals
#"Added Custom" = Table.AddColumn(#"Sorted Rows", "Headers", each [Attribute] & "#(lf)" & "Exposure " & Text.From([Exposure Level])),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Sample ID","Exposure Level", "Attribute"}),
//custom pivot function for non-aggregation
pivotAll = fnPivotAll(#"Removed Columns","Headers","Value")
in
pivotAll
М-код
Пользовательская функция с именем fnPivotAll
//credit: Cam Wallace https://www.dingbatdata.com/2018/03/08/non-aggregate-pivot-with-multiple-rows-in-powerquery/
(Source as table,
ColToPivot as text,
ColForValues as text)=>
let
PivotColNames = List.Buffer(List.Distinct(Table.Column(Source,ColToPivot))),
#"Pivoted Column" = Table.Pivot(Source, PivotColNames, ColToPivot, ColForValues, each _),
TableFromRecordOfLists = (rec as record, fieldnames as list) =>
let
PartialRecord = Record.SelectFields(rec,fieldnames),
RecordToList = Record.ToList(PartialRecord),
Table = Table.FromColumns(RecordToList,fieldnames)
in
Table,
#"Added Custom" = Table.AddColumn(#"Pivoted Column", "Values", each TableFromRecordOfLists(_,PivotColNames)),
#"Removed Other Columns" = Table.RemoveColumns(#"Added Custom",PivotColNames),
#"Expanded Values" = Table.ExpandTableColumn(#"Removed Other Columns", "Values", PivotColNames)
in
#"Expanded Values"
Спасибо! Проблема: когда я помещаю ваш код в редакторе Power Query в файл Excel с таблицей, он говорит Expression.Error: We couldn't find an Excel table named 'Table1'.
Когда я открываю новый файл Excel и вручную добавляю другой в качестве источника, в нем есть исходные строки Source = Excel.Workbook(File.Contents("C:\Users\[my user]\OneDrive\Desktop\Test.xlsx"), null, true),
, за которыми следует Sheet1_Sheet = Source{[Item = "Sheet1",Kind = "Sheet"]}[Data],
. Когда я использую ваш код, но заменяю исходную строку этим, он говорит Expression.Error: The column 'Sample ID' of the table wasn't found.
Есть идеи?
@user3316549 user3316549 Если ваша таблица данных не Table1
, измените имя таблицы во второй строке кода.
Хорошо, спасибо, я исправил эту проблему! Но теперь я понимаю, что могло быть некоторое недопонимание - в моей примерной таблице была только одна из каждой комбинации переменных уровня воздействия и наркотика (1A, 1B, 2A, 2B, 3A, 3B и т. д.). Однако фактическая таблица данных содержит десятки образцов, несколько из которых имеют одинаковую комбинацию переменных (например, может быть десять образцов на уровне воздействия 1 с наркотиком А). Мне нужно, чтобы все числа Exposure 1, Score 1 находились в одном столбце (и количество образцов уровня 1 отличается от количества образцов уровня 2 и т. д.). Имеет ли это смысл, и есть ли способ сделать это?
@ user3316549 Да, это так, и для этого требуется другое решение. Нередко, когда представлена нерепрезентативная выборка данных, создается решение, которое работает с представленными данными, но не с реальными данными. Мне придется подумать об этом.
@user3316549 user3316549 См. редактирование для решения вашей второй проблемы.
Вероятно, вы можете сделать это с помощью Power Query, возможно, с помощью Power Pivot. Но я не понимаю, как вы получаете результаты, которые вы показываете, на основе исходного набора данных, который вы показываете. Кроме того, чтобы сделать данные полезными для устранения неполадок, отредактируйте свой вопрос, чтобы опубликовать его в виде текста, возможно, с помощью этого Генератора таблиц уценки