80

Rから始めたばかりで、奇妙な動作に遭遇しました。空のデータフレームに最初の行を挿入すると、元の列名が失われます。

例:

a<-data.frame(one = numeric(0), two = numeric(0))
a
#[1] one two
#<0 rows> (or 0-length row.names)
names(a)
#[1] "one" "two"
a<-rbind(a, c(5,6))
a
#  X5 X6
#1  5  6
names(a)
#[1] "X5" "X6"

ご覧のとおり、列名12はX5X6に置き換えられました。

誰かがこれが発生する理由を教えてもらえますか?列名を失うことなくこれを行う正しい方法はありますか?

ショットガンの解決策は、名前を補助ベクトルに保存し、データフレームでの作業が終了したらそれらを追加し直すことです。

ありがとう

コンテクスト:

いくつかのデータを収集し、パラメーターとして受け取ったデータフレームに新しい行として追加する関数を作成しました。データフレームを作成し、データソースを反復処理して、data.frameを各関数呼び出しに渡して結果を入力します。

4

9 に答える 9

40

rbindヘルプページは次のように指定しています。

'cbind'('rbind')の場合、Sの互換性のために、結果の行(列)がゼロでない限り、長さがゼロのベクトル('NULL'を含む)は無視されます。(ゼロエクステントマトリックスはS3では発生せず、Rでは無視されません。)

したがって、実際には、あなたの指示でaは無視されます。rbind完全に無視されているわけではないようです。データフレームであるため、rbind関数は次のように呼び出されるためrbind.data.frameです。

rbind.data.frame(c(5,6))
#  X5 X6
#1  5  6

たぶん、行を挿入する1つの方法は次のようになります。

a[nrow(a)+1,] <- c(5,6)
a
#  one two
#1   5   6

ただし、コードによっては、より良い方法がある場合があります。

于 2011-03-08T11:14:16.097 に答える
16

この問題にほとんど屈服していました。

stringsAsFactor1)に設定されたデータフレームを作成するFALSEか、次の問題に直接遭遇します

2)使用しないでくださいrbind-なぜそれが列名を台無しにしているのか分かりません。単にこのようにしてください:

df[nrow(df)+1,] <- c("d","gsgsgd",4)

df <- data.frame(a = character(0), b=character(0), c=numeric(0))

df[nrow(df)+1,] <- c("d","gsgsgd",4)

#Warnmeldungen:
#1: In `[<-.factor`(`*tmp*`, iseq, value = "d") :
#  invalid factor level, NAs generated
#2: In `[<-.factor`(`*tmp*`, iseq, value = "gsgsgd") :
#  invalid factor level, NAs generated

df <- data.frame(a = character(0), b=character(0), c=numeric(0), stringsAsFactors=F)

df[nrow(df)+1,] <- c("d","gsgsgd",4)

df
#  a      b c
#1 d gsgsgd 4
于 2013-03-30T12:20:08.203 に答える
9

回避策は次のとおりです。

a <- rbind(a, data.frame(one = 5, two = 6))

?rbindオブジェクトをマージするには、一致する名前が必要であると述べています。

次に、最初のデータフレームから列のクラスを取得し、(位置ではなく)名前で列を照合します。

于 2011-03-08T11:14:08.880 に答える
8

FWIW、代替設計では、データフレームにバインドする代わりに、関数が2つの列のベクトルを構築する場合があります。

ones <- c()
twos <- c()

関数のベクトルを変更します。

ones <- append(ones, 5)
twos <- append(twos, 6)

必要に応じて繰り返し、data.frameを一度に作成します。

a <- data.frame(one=ones, two=twos)
于 2011-03-08T12:01:22.030 に答える
2

これを一般的に、列名の再入力を最小限に抑えて機能させる1つの方法は、次のとおりです。この方法では、NAまたは0をハッキングする必要はありません。

rs <- data.frame(i=numeric(), square=numeric(), cube=numeric())
for (i in 1:4) {
    calc <- c(i, i^2, i^3)
    # append calc to rs
    names(calc) <- names(rs)
    rs <- rbind(rs, as.list(calc))
}

rsは正しい名前になります

> rs
    i square cube
1   1      1    1
2   2      4    8
3   3      9   27
4   4     16   64
> 

これをよりクリーンに行う別の方法は、data.tableを使用することです。

> df <- data.frame(a=numeric(0), b=numeric(0))
> rbind(df, list(1,2)) # column names are messed up
>   X1 X2
> 1  1  2

> df <- data.table(a=numeric(0), b=numeric(0))
> rbind(df, list(1,2)) # column names are preserved
   a b
1: 1 2

data.tableはdata.frameでもあることに注意してください。

> class(df)
"data.table" "data.frame"
于 2016-06-25T13:44:14.200 に答える
1

あなたはこれを行うことができます:

最初のデータフレームに1行を指定します

 df=data.frame(matrix(nrow=1,ncol=length(newrow))

新しい行を追加してNASを取り出します

newdf=na.omit(rbind(newrow,df))

ただし、newrowにNAがないか、NAも消去されることに注意してください。

乾杯アグス

于 2013-11-12T13:13:32.397 に答える
1

次のソリューションを使用して、空のデータフレームに行を追加します。

d_dataset <- 
  data.frame(
    variable = character(),
    before = numeric(),
    after = numeric(),
    stringsAsFactors = FALSE)

d_dataset <- 
  rbind(
    d_dataset,
      data.frame(
        variable = "test",
        before = 9,
        after = 12,
        stringsAsFactors = FALSE))  

print(d_dataset)

variable before after  
1     test      9    12

HTH。

敬具

ゲオルク

于 2017-01-12T09:48:23.030 に答える
0

この由緒あるRの煩わしさを調査すると、このページにたどり着きました。私はGeorgの優れた答え( https://stackoverflow.com/a/41609844/2757825 )にもう少し説明を追加したいと思いました。これはOPによって引き起こされた問題(フィールド名の喪失)を解決するだけでなく、要因へのすべてのフィールド。私にとって、これら2つの問題は一緒に起こります。ベースRで、余分なコードを記述せずに、データフレームの定義、行の追加という2つの異なる操作を保持するソリューションが必要でした。これは、Georgの回答が提供するものです。

以下の最初の2つの例は問題を示し、3番目と4番目はGeorgの解決策を示しています。

例1:rbindを使用して新しい行をベクトルとして追加します

  • 結果:列名が失われ、すべての変数が因子に変換されます
my.df <- data.frame(
    table = character(0),
    score = numeric(0),
    stringsAsFactors=FALSE
    )
my.df <- rbind(
    my.df, 
    c("Bob", 250) 
    )
    
my.df
  X.Bob. X.250.
1    Bob    250

str(my.df)
'data.frame':   1 obs. of  2 variables:
 $ X.Bob.: Factor w/ 1 level "Bob": 1
 $ X.250.: Factor w/ 1 level "250": 1

例2:rbind内のデータフレームとして新しい行を追加します

  • 結果:列名は保持されますが、文字変数は因子に変換されます。
my.df <- data.frame(
    table = character(0),
    score = numeric(0),
    stringsAsFactors=FALSE
    )
my.df <- rbind(
    my.df, 
    data.frame(name="Bob", score=250) 
    )
    
my.df
      name score
1 Bob  250

str(my.df)
'data.frame':   1 obs. of  2 variables:
 $ name : Factor w/ 1 level "Bob": 1
 $ score: num 250

例3:stringsAsFactors = FALSEを使用して、rbind内の新しい行をデータフレームとして追加します

  • 結果:問題は解決しました。
my.df <- data.frame(
    table = character(0),
    score = numeric(0),
    stringsAsFactors=FALSE
    )
my.df <- rbind(
    my.df, 
    data.frame(name="Bob", score=250, stringsAsFactors=FALSE) 
    )
    
my.df
      name score
1 Bob  250

str(my.df)
'data.frame':   1 obs. of  2 variables:
 $ name : chr "Bob"
 $ score: num 250

例4:例3と同様ですが、一度に複数の行を追加します。

my.df <- data.frame(
    table = character(0),
    score = numeric(0),
    stringsAsFactors=FALSE
    )
my.df <- rbind(
    my.df, 
    data.frame(
        name=c("Bob", "Carol", "Ted"), 
        score=c(250, 124, 95), 
        stringsAsFactors=FALSE) 
    )

str(my.df)
'data.frame':   3 obs. of  2 variables:
 $ name : chr  "Bob" "Carol" "Ted"
 $ score: num  250 124 95

my.df
   name score
1   Bob   250
2 Carol   124
3   Ted    95

于 2022-02-01T19:58:05.537 に答える
-1

を使用してdata.frameを作成する代わりに、numeric(0)を使用しますas.numeric(0)

a<-data.frame(one=as.numeric(0), two=as.numeric(0))

これにより、追加の初期行が作成されます

a
#    one two
#1   0   0

追加の行をバインドします

a<-rbind(a,c(5,6))
a
#    one two
#1   0   0
#2   5   6

次に、負のインデックスを使用して最初の(偽の)行を削除します

a<-a[-1,]
a

#    one two
#2   5   6

注:インデックスを台無しにします(左端)。私はそれを防ぐ方法を理解していません(他の誰か?)が、ほとんどの場合、それはおそらく問題ではありません。

于 2014-05-19T02:29:15.417 に答える