为了避免交换柱的这一步,你可以通过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$
从实现准的Perl风格的字符串替换的gsubfn包:
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 home page和fn$
看到gsubfn home page。
这只是有点不清楚......对于上面的列,你想让df带上y的值iff x是一个空字符串,否则从x取值? – 2013-02-24 06:26:07
你如何做你的合并?你能给出上下文吗?并请提供一个可重复的例子。 – agstudy 2013-02-24 06:26:10