2013-09-29 9 views
11

私はこのような簡単な質問に対する答えを忘れた場合、私を許してください。cbind:欠損値をNAに設定する方法はありますか?

cbind()を使用して2つの列をバインドします。それらの1つは、短い長さの単一のエントリです。

Rに欠損値のNAを指定できますか?

ドキュメントではdeparse.level引数について説明していますが、これは私の解決策ではありません。

また、私が大胆な場合は、短い列の前に素早く数字を入力してNAを追加することもできますか?

答えて

7

このお試しください:関係なく、どのベクトルの短い私は、これはDWINが提案するものに似た何かをして働くだろうと思い

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(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) 

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

上記のコードは、縮約することもできます。

私は大胆かもしれ場合

「また、また、NAのと短い列を付加する簡単な方法があるでしょう。ここ

が、私は疑問に対処するために思い付いたものです

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

EDIT ? "

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) 

このバージョンでは、あなたが異なるモードの2つのベクトルCBINDすることができます:バック私は一緒に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

Aをこの種のことをすることを意図していました。現在の形式では、ベクトルとしてdata.frame sと行列を入力として扱うことができるはずです。今の

、関数はここにある:ここでhttps://gist.github.com/mrdwab/6789277

は、1つの機能を使用する方法である:必要な

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 

3つの関数があるpadNAdotnames、およびCbind、あります

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パッケージがすでに行の数が異なるdata.frame sおよび行列をINGのcbindを処理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)があります。 –

関連する問題