2013-09-29 54 views
11

請原諒我,如果我錯過了這樣一個簡單的問題的答案。我想用cbind()來綁定兩列。其中之一是長度較短的單個條目。cbind:有沒有辦法將缺失值設置爲NA?

我可以讓R爲缺失值提供NA嗎?

該文檔討論了一個deparse.level的論點,但這似乎並不是我的解決方案。

此外,如果我可能如此大膽,是否還會有一種快速方法來預測較短的列NA的?

回答

7

試試這個:

x <- c(1:5) 
y <- c(4:1) 
length(y) = length(x) 
cbind(x,y) 
    x y 
[1,] 1 4 
[2,] 2 3 
[3,] 3 2 
[4,] 4 1 
[5,] 5 NA 

或本:

x <- c(4:1) 
y <- c(1:5) 
length(x) = length(y) 
cbind(x,y) 
     x y 
[1,] 4 1 
[2,] 3 2 
[3,] 2 3 
[4,] 1 4 
[5,] NA 5 

我認爲這會做類似於迪文建議的東西,無論工作,其中矢量較短:

x <- c(4:1) 
y <- c(1:5) 

lengths <- max(c(length(x), length(y))) 
length(x) <- lengths 
length(y) <- lengths 
cbind(x,y) 

上面的代碼也可以縮寫爲:

x <- c(4:1) 
y <- c(1:5) 
length(x) <- length(y) <- max(c(length(x), length(y))) 
cbind(x,y) 

編輯

這裏是我想出瞭解決這樣的問題:

「此外,如果我可以大膽,將有也是在前面加上NA的短欄的快捷方式?」

由Matt O'Brien插入原始文章。

x <- c(4:1) 
y <- c(1:5) 

first <- 1 # 1 means add NA to top of shorter vector 
      # 0 means add NA to bottom of shorter vector 

if(length(x)<length(y)) { 
    if(first==1) x = c(rep(NA, length(y)-length(x)),x);y=y 
    if(first==0) x = c(x,rep(NA, length(y)-length(x)));y=y 
} 

if(length(y)<length(x)) { 
    if(first==1) y = c(rep(NA, length(x)-length(y)),y);x=x 
    if(first==0) y = c(y,rep(NA, length(x)-length(y)));x=x 
} 

cbind(x,y) 

#  x y 
# [1,] NA 1 
# [2,] 4 2 
# [3,] 3 3 
# [4,] 2 4 
# [5,] 1 5 

這裏是一個函數:

x <- c(4:1) 
y <- c(1:5) 

first <- 1 # 1 means add NA to top of shorter vector 
      # 0 means add NA to bottom of shorter vector 

my.cbind <- function(x,y,first) { 

    if(length(x)<length(y)) { 
    if(first==1) x = c(rep(NA, length(y)-length(x)),x);y=y 
    if(first==0) x = c(x,rep(NA, length(y)-length(x)));y=y 
    } 

    if(length(y)<length(x)) { 
    if(first==1) y = c(rep(NA, length(x)-length(y)),y);x=x 
    if(first==0) y = c(y,rep(NA, length(x)-length(y)));x=x 
    } 

    return(cbind(x,y)) 

} 

my.cbind(x,y,first) 

my.cbind(c(1:5),c(4:1),1) 
my.cbind(c(1:5),c(4:1),0) 
my.cbind(c(1:4),c(5:1),1) 
my.cbind(c(1:4),c(5:1),0) 
my.cbind(c(1:5),c(5:1),1) 
my.cbind(c(1:5),c(5:1),0) 

這個版本允許你cbind不同模式的兩個向量:

x <- c(4:1) 
y <- letters[1:5] 

first <- 1 # 1 means add NA to top of shorter vector 
      # 0 means add NA to bottom of shorter vector 

my.cbind <- function(x,y,first) { 

    if(length(x)<length(y)) { 
    if(first==1) x = c(rep(NA, length(y)-length(x)),x);y=y 
    if(first==0) x = c(x,rep(NA, length(y)-length(x)));y=y 
    } 

    if(length(y)<length(x)) { 
    if(first==1) y = c(rep(NA, length(x)-length(y)),y);x=x 
    if(first==0) y = c(y,rep(NA, length(x)-length(y)));x=x 
    } 

    x <- as.data.frame(x) 
    y <- as.data.frame(y) 

    return(data.frame(x,y)) 

} 

my.cbind(x,y,first) 

# x y 
# 1 NA a 
# 2 4 b 
# 3 3 c 
# 4 2 d 
# 5 1 e 

my.cbind(c(1:5),letters[1:4],1) 
my.cbind(c(1:5),letters[1:4],0) 
my.cbind(c(1:4),letters[1:5],1) 
my.cbind(c(1:4),letters[1:5],0) 
my.cbind(c(1:5),letters[1:5],1) 
my.cbind(c(1:5),letters[1:5],0) 
+1

只有當y比x短時才能正常工作。 –

+0

@DWin如果'x'較短,您可不要只改變順序並使用'length(x)= length(y)'? –

+2

當然,但您應該使用測試,然後執行正確的操作。 –

4

前陣子我已經放在一起稱爲Cbind一個函數,本來打算做這種事情。在目前的形式下,它應該能夠處理矢量,data.frame和矩陣作爲輸入。

目前,該功能是在這裏:https://gist.github.com/mrdwab/6789277

下面是一個如何使用功能:需要

x <- 1:5 
y <- letters[1:4] 
z <- matrix(1:4, ncol = 2, dimnames = list(NULL, c("a", "b"))) 
Cbind(x, y, z) 
# x y z_a z_b 
# 1 1 a 1 3 
# 2 2 b 2 4 
# 3 3 c NA NA 
# 4 4 d NA NA 
# 5 5 <NA> NA NA 
Cbind(x, y, z, first = FALSE) 
# x y z_a z_b 
# 1 1 <NA> NA NA 
# 2 2 a NA NA 
# 3 3 b NA NA 
# 4 4 c 1 3 
# 5 5 d 2 4 

的三種功能是padNAdotnamesCbind,這是定義如下:

padNA <- function (mydata, rowsneeded, first = TRUE) { 
## Pads vectors, data.frames, or matrices with NA 
    temp1 = colnames(mydata) 
    rowsneeded = rowsneeded - nrow(mydata) 
    temp2 = setNames(
    data.frame(matrix(rep(NA, length(temp1) * rowsneeded), 
         ncol = length(temp1))), temp1) 
    if (isTRUE(first)) rbind(mydata, temp2) 
    else rbind(temp2, mydata) 
} 

dotnames <- function(...) { 
## Gets the names of the objects passed through ... 
    vnames <- as.list(substitute(list(...)))[-1L] 
    vnames <- unlist(lapply(vnames,deparse), FALSE, FALSE) 
    vnames 
} 

Cbind <- function(..., first = TRUE) { 
## cbinds vectors, data.frames, and matrices together 
    Names <- dotnames(...) 
    datalist <- setNames(list(...), Names) 
    nrows <- max(sapply(datalist, function(x) 
    ifelse(is.null(dim(x)), length(x), nrow(x)))) 
    datalist <- lapply(seq_along(datalist), function(x) { 
    z <- datalist[[x]] 
    if (is.null(dim(z))) { 
     z <- setNames(data.frame(z), Names[x]) 
    } else { 
     if (is.null(colnames(z))) { 
     colnames(z) <- paste(Names[x], sequence(ncol(z)), sep = "_") 
     } else { 
     colnames(z) <- paste(Names[x], colnames(z), sep = "_") 
     } 
    } 
    padNA(z, rowsneeded = nrows, first = first) 
    }) 
    do.call(cbind, datalist) 
} 

我停止工作的部分原因是gdata程序包已經有一個函數cbindX來處理和具有不同行數的矩陣。它不會直接在矢量上工作,因此您需要先將它們轉換爲data.frame

library(gdata) 
cbindX(data.frame(x), data.frame(y), z) 
# x y a b 
# 1 1 a 1 3 
# 2 2 b 2 4 
# 3 3 c NA NA 
# 4 4 d NA NA 
# 5 5 <NA> NA NA 
+0

+1提到'cbindX' - 工作得很好。這裏是[代碼](https://github.com/cran/gdata/blob/master/R/cbindX.R) –

相關問題