连接具有不同列顺序的多个表团队,
我有 5 个 csv 文件,每个文件都有 200 列(并非每个文件都有相同的列数)。 每个文件都有不同顺序的列。 我想编写一个脚本,让用户选择所有 5 个文件,然后合并所有 5 个文件(删除不匹配的列)并将合并的 csv 文件保存到所需位置。 我想使用类似于 (data = Open(Pick File("Choose the File", x)), x 是目录) 的命令来选择文件。
谢谢
回复:连接具有不同列顺序的多个表谢谢@tx尼尔森
你总是一个很大的帮助。回复:连接具有不同列顺序的多个表这是脚本的重写,选择要在一个选择中连接的所有文件,然后运行一个小脚本将它们放在一起,只保留找到匹配的列。 我已根据您的规格构建了它,但是可以轻松更改它以允许连接任意数量的文件
Names Default To Here( 1 );
inputDirectory = "C:\";
// Select the files to be read in......this can be any number of files
filePath = Pick File(
"Choose the File to be Concatenated to:",
inputDirectory,
{"CSV Files|csv;", "All Files|*"},
1,
0,
""
);
// Open the first file
dtMain = Open( filePath, invisible );
files = Pick File(
"Choose the Additional 4 Files to Read In:",
inputDirectory,
{"CSV Files|csv;", "All Files|*"},
1,
0,
"",
multiple
);
// Validate that files have been read in
If( Try( N Items( files ), 0 ) == 4,
Dialog( "Incorrect number of files were read in."
"Only 4 additional files can be read in");
Throw( "Incorrect number of files were read in" );
);
// Read in the remaining files and process them
For( i = 2, i <= N Items( Files ), i++,
Try( dtConCat = Open( Files[i], invisible ) );
mainColList = dtMain << Get Column Names( string );
conCatColList = dtConCat << Get Column Names( string );
// Delete the columns in the dtConCat table that do not exist in the dtMain table
delList = {};
For( k = 1, k <= N Items( conCatColList ), k++,
If( N Rows( Loc( mainColList, conCatColList[k] ) ) == 0,
Insert Into( delList, conCatColList[k] )
)
);
If( N Items( delList ) > 0,
dtConCat << delete columns( delList )
);
// Delete the columns in the dtMain table that were not found in the dtConCat table
delList = {};
For( k = 1, k <= N Items( mainColList ),
k++,
If( N Rows( Loc( conCatColList, mainColList[k] ) ) == 0,
Insert Into( delList, mainColList[k] )
)
);
If( N Items( delList ) > 0,
dtMain << delete columns( delList )
);
// If any columns still remain in the two tables, then concatenate them together
If( N Cols( dtMain ) > 0 & N Cols( dtConCat ) > 0,
dtMain = dtMain << Concatenate( dtConCat, Append to First Table )
);
// Close the no longer needed file
Close( dtConCat, nosave );
);
// Make the main file visible
dtMain << show window( 1 );
回复:连接具有不同列顺序的多个表@拉贾特,
我不明白为什么你需要创建一个新表。 我会做这样的事情。
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
OriginalColOrder = dt << Get Column Names("string");
dt << Reorder By Name();
SortedColOrder = dt << Get Column Names("string");
Show(OriginalColOrder);
Show(SortedColOrder); 这些列表为您提供排序顺序和原始顺序。 另外,请分享您到目前为止所尝试过的内容,以便更容易了解您的前进方向。 我无法准确理解您到目前为止所尝试过的以及失败的地方。 如果您无法共享数据,请尝试创建一些示例数据,以便每个人都可以轻松重现问题并帮助指导您。
回复:连接具有不同列顺序的多个表@uday_guntupalli
可以帮我编写语法来保存原始顺序并使用保存的顺序对最终表重新排序吗?
谢谢回复:连接具有不同列顺序的多个表@拉贾特,
dt << Reorder By Name();
回复:连接具有不同列顺序的多个表谢谢@uday_guntupalli
如果我们可以重新排序列并使它们具有相同的顺序。 之后我们将连接所有表。
你能帮我编写语法来根据第一个表重新排序所有表的列,然后我们将在循环中使用连接命令。 如果不可能,我们可以保存第一个表的原始列顺序,然后用它们的名称对所有表重新排序,然后在循环中连接。 最后,我们将根据之前保存的列顺序对最终表重新排序。
@Craige_Hales @tx尼尔森你有解决这个问题的方法吗?
谢谢。 感谢您的帮助。回复:连接具有不同列顺序的多个表@拉贾特,
ThisListAsAA = Associative Array(ThisList);
ThisListAsAAKeys =ThisListAsAA << Get Keys;
If(i == 1,
CommonItems = ThisListAsAAKeys;
,
// else
CommonItems << Intersect(ThisListAsAAKeys);
);
关联数组具有一对一的关系或映射。 因此,一旦我们构造了关联数组,第二行就会尝试提取关联数组映射中的唯一键。 至于 If 块,请考虑集合论,当 i = 1 时,我们将关联数组 1 的唯一键分配给结果。 从那时起,我们反复将其与其他关联数组相交,最终得到一个列表,该列表仅包含所有关联数组中共有的元素。
Select( :name, :age, :sex, :height, :weight ),
By Row Number
这是我的示例中的一个拼写错误。 Select(CommonItems) 是合适的。
不知道Concatenate行不行,欢迎尝试
回复:连接具有不同列顺序的多个表@uday_guntupalli
感谢您的大力帮助。
我的评论很少
- 所有表都有不同的行数。
- 我想连接(最终表中的行数将是单个表的行数之和)不连接表的表。 连接循环的工作原理是否相同?
另外,您能帮我理解以下命令吗?
- 在循环中查找公共列名称。 您能解释一下以下几行吗?
ThisListAsAA <SPAN class="token operator">=</SPAN> <SPAN class="token function">Associative Array</SPAN><SPAN class="token punctuation">(</SPAN>ThisList<SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">;</SPAN>
ThisListAsAAKeys <SPAN class="token operator">=</SPAN>ThisListAsAA <SPAN class="token operator"><</SPAN><SPAN class="token operator"><</SPAN><SPAN class="token messages"> Get Keys</SPAN><SPAN class="token punctuation">;</SPAN>
<SPAN class="token function">If</SPAN><SPAN class="token punctuation">(</SPAN>i <SPAN class="token operator">==</SPAN> <SPAN class="token number">1</SPAN><SPAN class="token punctuation">,</SPAN>
CommonItems <SPAN class="token operator">=</SPAN> ThisListAsAAKeys<SPAN class="token punctuation">;</SPAN>
<SPAN class="token punctuation">,</SPAN>
<SPAN class="token comment">// else </SPAN>
CommonItems <SPAN class="token operator"><</SPAN><SPAN class="token operator"><</SPAN><SPAN class="token messages"> Intersect</SPAN><SPAN class="token punctuation">(</SPAN>ThisListAsAAKeys<SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">;</SPAN>
<SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">;</SPAN>
据我了解“此列表为 AA “,”此列表" 将被存储为关联数组。 请帮助理解接下来的两行。 - 在连接表格的循环中,您能解释一下以下几行吗?
Select<SPAN class="token punctuation">(</SPAN> <SPAN class="token punctuation">:</SPAN>name<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>age<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>sex<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>height<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>weight <SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">,</SPAN>
By Row Number
没有带有列名的列:名称,:年龄等,并且我们无法手动写入选择列,因为数量巨大。 另外,我们不能按行号连接,因为行数不同,并且我们想要连接表而不是连接。
谢谢
回复:连接具有不同列顺序的多个表@拉贾特,
我假设(我不知道它有多有效)您有相同的行数。
// Define Your Directory and a list to hold File Paths
MyDirectory = "C:\" ;
nFiles = 5;
MyFilePaths = {};
ColNamesListOfList = {};
OpenDts = {};
// Test if Directory exists and get all file paths
Try( If(Directory Exists(MyDirectory),
for(i = 1 , i <= nFiles, i ++,
FilePath = Pick File( "Select File", MyDirectory);
Insert Into(MyFilePaths,FilePath);
);
,
// else
Throw()
),
"Unable to Open File";
);
// Get List of All Column Names
for(i = 1, i <= nFiles, i++,
OpenDts[i] = Open(MyDirectory || "\" || FilePath[i],"Invisible");
ColNames = OpenDts[i] << Get Column Names("String");
Insert Into(ColNamesListOfList,ColNames);
);
// Find Common Column Names
for(i = 1, i <= nFiles, i++,
ThisList = ColNamesListOfList[i];
ThisListAsAA = Associative Array(ThisList);
ThisListAsAAKeys =ThisListAsAA << Get Keys;
If(i == 1,
CommonItems = ThisListAsAAKeys;
,
// else
CommonItems << Intersect(ThisListAsAAKeys);
);
);
// Concatenate
for(i = 1, i <= nFiles, i++,
If(i == 1,
dt_Results = OpenDts[i];
,
dt_Results << Join(With( OpenDts[i]),
Merge Same Name Columns,
Select( :name, :age, :sex, :height, :weight ),
By Row Number // assuming that the tables have the same number of rows
);
);
); 回复:连接具有不同列顺序的多个表谢谢乌代。 我想连接公共列。回复:连接具有不同列顺序的多个表@拉贾特,
看看您所描述的问题,让我们将其分解为多个步骤。
第 1 步:选择所需的文件 - 使用 Pick File ()
),
"Unable to Open File";
); // Define Your Directory and a list to hold File Paths
MyDirectory = "C:\" ;
nFiles = 5;
MyFilePaths = {};
OpenDts = {};
// Test if Directory exists and get all file paths
Try( If(Directory Exists(MyDirectory),
for(i = 1 , i <= nFiles, i ++,
FilePath = Pick File( "Select File", MyDirectory);
Insert Into(MyFilePaths,FilePath);
); <BR /> , <BR /> // else<BR /> Throw()<BR />
第 2 步:循环遍历文件,打开并连接公共列
在这里,我有一个问题想问你。 最终表中是否有您期望的列列表(或者)它只是所有 5 个 csv 文件中的公共列吗?