web-dev-qa-db-ja.com

等しくない長さのデータフレームを作成する

データフレーム列の行数は同じでなければなりませんが、長さが等しくないデータフレームを作成する方法はありますか。リストの別の要素として保存することに興味はありません。なぜなら、この情報をcsvファイルとしてメールで送信する必要があることが多く、これはデータフレームとして最も簡単だからです。

_x = c(rep("one",2))
y = c(rep("two",10))
z = c(rep("three",5))
cbind(x,y,z)
_

上記のコードでは、cbind()関数は短い列をリサイクルするだけなので、各列に10個の要素があります。長さが2、10、5になるように変更するにはどうすればよいですか。

過去にこれを行ってきましたが、次のようにしますが、非効率的です。

_  df = data.frame(one=c(rep("one",2),rep("",8)), 
           two=c(rep("two",10)), three=c(rep("three",5), rep("",5))) 
_
20
ATMathew

申し訳ありませんが、これはまさにあなたが尋ねたものではありませんが、私はあなたが望むものを得るための別の方法があるかもしれないと思います。

まず、ベクトルの長さが異なる場合、データは実際には表形式ではありませんか?別のCSVファイルに保存するだけではどうですか?複数のオブジェクトを保存できるascii形式を試すこともできます( json[〜#〜] xml [〜#〜] )。

データが本当に表形式であると思う場合は、NAをパディングできます。

> x = 1:5
> y = 1:12
> max.len = max(length(x), length(y))
> x = c(x, rep(NA, max.len - length(x)))
> y = c(y, rep(NA, max.len - length(y)))
> x
 [1]  1  2  3  4  5 NA NA NA NA NA NA NA
> y
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

等しくない列を持つdata.frameを絶対に作成する必要がある場合、自分の責任でチェックを覆すことができます。

> x = 1:5
> y = 1:12
> df = list(x=x, y=y)
> attributes(df) = list(names = names(df),
    row.names=1:max(length(x), length(y)), class='data.frame')
> df
      x  y
1     1  1
2     2  2
3     3  3
4     4  4
5     5  5
6  <NA>  6
7  <NA>  7
 [ reached getOption("max.print") -- omitted 5 rows ]]
Warning message:
In format.data.frame(x, digits = digits, na.encode = FALSE) :
  corrupt data frame: columns will be truncated or padded with NAs
26
Owen

パディングへの別のアプローチ:

_na.pad <- function(x,len){
    x[1:len]
}

makePaddedDataFrame <- function(l,...){
    maxlen <- max(sapply(l,length))
    data.frame(lapply(l,na.pad,len=maxlen),...)
}

x = c(rep("one",2))
y = c(rep("two",10))
z = c(rep("three",5))

makePaddedDataFrame(list(x=x,y=y,z=z))
_

na.pad()関数は、存在しない要素にインデックスを付けようとすると、Rが自動的にNAでベクトルをパディングするという事実を利用します。

makePaddedDataFrame()は、最も長いものを見つけ、残りを一致する長さになるまで埋め込みます。

6
Peter M

@goodsideの答えを増幅するには、次のようなことができます

L <- list(x,y,z)
cfun <- function(L) {
  pad.na <- function(x,len) {
   c(x,rep(NA,len-length(x)))
  }
  maxlen <- max(sapply(L,length))
  do.call(data.frame,lapply(L,pad.na,len=maxlen))
}

(テストなし)。

5
Ben Bolker

これは不可能です。最も近いのは、「空の」スペースに値NAを入力することです。

3
goodside