R中的动态合并

时间:2015-10-16 15:20:16

标签: r merge

我有一个示例过滤表,如下所示,是一个大的源数据表。我需要使用这两个表进行合并。如果过滤器表中没有列包含ALL,请使用三列进行合并(使用Tran=1001Acct=1& Co=a与数据表进行内连接。)如果其中一个,即Tran拥有ALL,使用剩余的两列进行合并(使用Acct=3& Co=c进行连接)。如果其中两个(即TranAcct)具有All,请使用剩余的一列进行合并(使用Co=b进行连接)。

真正的问题是列数是不确定的。

任何人都可以帮我吗?

Tran    Acct    Co
1001    1        a
1002    ALL     ALL
ALL     ALL      b
ALL      4      ALL
1003     2      ALL
ALL      3       c
1004     ALL    d

1 个答案:

答案 0 :(得分:2)

您必须使用ifelseifelse撰写一系列条件语句。我将使用%in%运算符来检查这一点。 %in%运算符返回一系列布尔值。最简单的方法是通过示例显示:

> x <- c(1, 2, 3, 4, 5)
> y <- c(2, 3, 4, 5, 6)
> x %in% y
[1] FALSE  TRUE  TRUE  TRUE  TRUE

请注意,它会返回FALSE作为第一个值,因为1x的值不在y中。你可以为&#34; ALL&#34;做同样的事情。数据集中的值。我假设你一行一行,因为你似乎暗示了你的问题。如果您需要先检查整个列,请告诉我(对于该情况,您可以使用any函数)。以下是您的第一个条件示例:

# Assume that df is your data.frame of data.

for (i in 1:length(df$Tran)) {

if (!("All" %in% df$Tran[i]) & !("ALL" %in% df$Acct[i]) & !("All" %in% df$Co[i])) {

# Do your merge here

}

if ( [Put your next condition here] ) {

# Do the appropriate merge for that condition

}

...

请注意,我使用了&#34;!&#34;运算符得到任何%in%返回的反函数,因为你希望它是ALL不在行中的情况。我现在意识到你可能已经完成了All != df$Tran[1],因为你要逐行进行,但是%in%可能会更有用,如果你最终选择整个列。

希望这有帮助!

使用新方法进行编辑,现在更清楚需要的是什么。所以我们必须找到&#34; ALL&#34;每行中的值,然后根据它们的数量以某种方式合并。有很多方法,但我喜欢这里的方法:

> test <- data.frame(a = "ALL", b = 2, c = "ALL", d = 3, e = "ALL")
> test
    a b   c d   e
1 ALL 2 ALL 3 ALL
> table(test[1, ] == "ALL")["TRUE"]
TRUE 
   3

基本上,我正在查看第一行,并在询问它是否包含字符串&#34; ALL&#34;时获取返回TRUE的数字。从这里你可以设置这个数字的条件。要在整个数据框架上自动化,请将其抛入for循环并设置&#34; 1&#34;等于&#34;我&#34;或者你对序列变量的任何东西都是。

获取哪些行&#34; ALL&#34;在它中(相反,它会告诉哪些行没有&#34; ALL&#34;在其中),你可以在每一行使用grep。这是一个简短的例子:

> # Initializing a sample data frame.
> df <- data.frame(a = "1", b = "ALL", c = "ALL", d = "5", e = "ALL")
> print(df)
  a   b   c d   e
1 1 ALL ALL 5 ALL
> 
> # Finding the column numbers that have "ALL" in it using grep.
> places <- grep("ALL", df[1, ])
> print(places)
[1] 2 3 5
> 
> # Each number corresponds to the order of the columns in the data frame and can be returned as such.
> nameCols <- names(df)[places]
> print(nameCols)
[1] "b" "c" "e"
> 
> # Likewise, you can find what columns did not have "ALL" in it by doing the opposite.
> nameColsNOT <- names(df)[-places]
> print(nameColsNOT)
[1] "a" "d"

通过循环为数据框中的每一行迭代此方法,并使用上面概述的条件方法。请注意,这要求您的所有列都是&#34;字符&#34;我认为已经是这种情况了。