爲了避免交換柱的這一步,你可以通過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