データフレームの行を連結する 質問する

データフレームの行を連結する 質問する

文字と数字を含むデータフレームを取得し、各行のすべての要素を 1 つの文字列に連結して、ベクトルの 1 つの要素として保存したいと思います。例として、文字と数字のデータフレームを作成し、貼り付け関数を使用して最初の行を連結し、値「A1」を返したいと思います。

df <- data.frame(letters = LETTERS[1:5], numbers = 1:5)
df

##   letters numbers
## 1       A       1
## 2       B       2
## 3       C       3
## 4       D       4
## 5       E       5

paste(df[1,], sep =".")
## [1] "1" "1"

したがって、paste は行の各要素を、それが因子であるかのように「対応するレベルのインデックス」に対応する整数に変換し、長さ 2 のベクトルを維持します。(文字に強制変換された因子がこのように動作することはわかっています/信じていますが、R は df[1,] を因子としてまったく保存していないため (is.factor() でテストされているため、それが実際にレベルのインデックスであることを確認できません)

is.factor(df[1,])
## [1] FALSE
is.vector(df[1,])
## [1] FALSE

つまり、それがベクトルでなければ、奇妙な動作をするのは当然ですが、それをベクトルに強制することはできません。

> is.vector(as.vector(df[1,]))
[1] FALSE

使用してもas.character私の試みには役立たなかったようです

この動作を説明できる人はいますか?

ベストアンサー1

他の人はあなたのコードが機能しない理由とそれを改善する方法に焦点を当てていますが、私はあなたが望む結果を得ることにもっと焦点を当てようと思います。あなたの説明からすると、貼り付けを使用してあなたが望むものを簡単に達成できるようです:

df <- data.frame(letters = LETTERS[1:5], numbers = 1:5, stringsAsFactors=FALSE)
paste(df$letters, df$numbers, sep=""))

## [1] "A1" "B2" "C3" "D4" "E5"

引数を使用しない場合は、df$letters文字を使用して変更できます。df$letters <- as.character(df$letters)stringsAsFactors

しかし、それがあなたの望むことではないと仮定しましょう。何百もの列があり、それらをすべて一緒に貼り付けたいと仮定しましょう。最小限の例でもそれを行うことができます。

df_args <- c(df, sep="")
do.call(paste, df_args)

## [1] "A1" "B2" "C3" "D4" "E5"

編集: 代替方法と説明:

あなたが抱えている問題は、因数を使用していることと、sepの代わりに引数を使用していることの組み合わせだとわかりましたcollapse(@adibender が指摘したように)。違いは、 はsep2 つの別々のベクトル間の区切り記号を提供し、collapseはベクトル内の区切り記号を提供することです。 を使用する場合df[1,]、 に単一のベクトルを提供するためpaste、引数を使用する必要がありますcollapse。すべての行を取得して連結するというアイデアを使用すると、次のコード行はまさにあなたが望むことを実行します。

apply(df, 1, paste, collapse="")

さて、説明に移ります。

なぜas.list動作しないのでしょうか?

as.listオブジェクトをリストに変換します。つまり、これは機能します。データフレームをリストに変換し、その後sep=""引数を無視します。cオブジェクトを結合します。技術的には、データフレームは、すべての列が要素であり、すべての要素が同じ長さである必要があるリストです。したがって、これを と結合するとsep=""、データフレームの列を要素とする通常のリストになります。

なぜ を使用するのですかdo.call?

do.callを使用すると、名前付きリストを引数として使用して関数を呼び出すことができます。 リストを に直接投げ込むことはできません。pasteはデータフレームを好まないためです。 はベクトルを連結するために設計されています。 はdfargs文字のベクトル、数値のベクトル、および sep ("" のみを含む長さ 1 のベクトル) を含むリストであることを覚えておいてください。 を使用するとdo.call、結果の paste 関数は基本的に になりますpaste(letters, numbers, sep)。しかし、元のデータフレームに列があり、その後ろに以前と同じようにセパレーターを追加した
場合はどうなるでしょうか。 を介した paste 関数は次のようになります。"letters", "numbers", "squigs", "blargs"do.call

paste(letters, numbers, squigs, blargs, sep)

つまり、任意の数の列に対して機能することがわかります。

おすすめ記事