我有一个示例过滤表,如下所示,是一个大的源数据表。我需要使用这两个表进行合并。如果过滤器表中没有列包含ALL,请使用三列进行合并(使用Tran=1001
,Acct=1
& Co=a
与数据表进行内连接。)如果其中一个,即Tran拥有ALL,使用剩余的两列进行合并(使用Acct=3
& Co=c
进行连接)。如果其中两个(即Tran
和Acct
)具有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
答案 0 :(得分:2)
您必须使用if
,elseif
和else
撰写一系列条件语句。我将使用%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
作为第一个值,因为1
中x
的值不在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;我认为已经是这种情况了。