为了避免交换列的这一步骤,您可以通过sqldf
包使用 SQL 来交换列(如果您的真正问题涉及可以同时完成的合并)。使用CASE
...WHEN
语法,您可以编写与我们相同的 if/else 逻辑:
library(sqldf)
colnames(df) <- gsub('[.]','_',colnames(df))
sqldf(" SELECT
CASE url_x WHEN '' THEN url_y ELSE url_x END as url ,
CASE source_x WHEN '' THEN source_y ELSE source_x END as source,
CASE id_x WHEN '' THEN id_y ELSE id_x END as id
FROM df")
可重现的例子
我们用一个可重现的例子来测试它:
# create some data
set.seed(1234)
df1 <- matrix(sample(c('a','b','d',''),3*5,rep=T),ncol=3)
df2 <- matrix(sample(c('c','b','','a'),3*5,rep=T),ncol=3)
colnames(df1) <- c('id','source','url')
colnames(df2) <- c('id','source','url')
df <- merge(df1,df2,by=0)
# run
library(sqldf)
colnames(df) <- gsub('[.]','_',colnames(df))
sqldf(" SELECT
CASE url_x WHEN '' THEN url_y ELSE url_x END as url ,
CASE source_x WHEN '' THEN source_y ELSE source_x END as source,
CASE id_x WHEN '' THEN id_y ELSE id_x END as id
FROM df")
url source id
1 d d a
2 d a d
3 b a d
4 a d d
5 b d c
哪里df
是:
Row_names id_x source_x url_x id_y source_y url_y
1 1 a d d a b a
2 2 d a d b b
3 3 d a b b c a
4 4 d d c c a
5 5 d b c c c
使用辅助函数
(1)如果我们有很多这些,那么我们可能想要使用一个辅助函数,该函数利用fn$
gsubfn 包中的实现准 perl 样式的字符串替换:
xy <- function(s) {
fn$identity("case $s_x when '' then $s_y else $s_x end as $s")
}
fn$sqldf("select `xy('url')`, `xy('source')`, `xy('id')` from df")
(2)或者这样做——将 SQL 语句存储到s
:
s <- fn$identity("select `xy('url')`, `xy('source')`, `xy('id')` from df")
sqldf(s)
更多信息
请参阅sqldf 主页和gsubfn 主页。fn$