15

元のデータフレーム名またはリストインデックスの記録を維持しながら、最終的にマージしたいデータフレームのリストがあります。これにより、すべての行をサブセット化することができます。これを達成するために、すべてのデータフレームに新しい変数「id」を追加したいと思います。これには、それが属するデータフレームの名前/インデックスが含まれています。

編集:「私の実際のコードでは、次のコードを使用して複数のファイルを読み取ることでデータフレーム変数が作成されるため、「files.to.read」リストにあるものだけが実際の名前を持っていません。それらが整列するかどうかはわかりませんデータフレームの順序:

mylist <- llply(files.to.read, read.csv)

いくつかの 投稿でいくつかの方法が強調されてい ます:

私は2つの同様の方法を試しました.1つ目はインデックスリストを使用しています:

df1 <- data.frame(x=c(1:5),y=c(11:15))
df2 <- data.frame(x=c(1:5),y=c(11:15))
mylist <- list(df1,df2)

# Adds a new coloumn 'id' with a value of 5 to every row in every dataframe.
# I WANT to change the value based on the list index.
mylist1 <- lapply(mylist, 
    function(x){
        x$id <- 5
        return (x)
    }
)
#Example of what I WANT, instead of '5'.
#> mylist1
#[[1]]
  #x  y id
#1 1 11  1
#2 2 12  1
#3 3 13  1
#4 4 14  1
#5 5 15  1
#
#[[2]]
  #x  y id
#1 1 11  2
#2 2 12  2
#3 3 13  2
#4 4 14  2
#5 5 15  2

2 番目は、リストの names() を渡そうとします。

# I WANT it to add a new coloumn 'id' with the name of the respective dataframe
# to every row in every dataframe.
mylist2 <- lapply(names(mylist), 
    function(x){
        portfolio.results[[x]]$id <- "dataframe name here"
        return (portfolio.results[[x]])
    }
)
#Example of what I WANT, instead of 'dataframe name here'.
# mylist2
#[[1]]
  #x  y id
#1 1 11  df1
#2 2 12  df1
#3 3 13  df1
#4 4 14  df1
#5 5 15  df1
#
#[[2]]
  #x  y id
#1 1 11  df2
#2 2 12  df2
#3 3 13  df2
#4 4 14  df2
#5 5 15  df2

しかし、names() 関数はデータフレームのリストでは機能しません。NULL を返します。最初の例で seq_along(mylist) を使用できますか。

「ソースIDとのマージ」全体を処理するためのアイデアまたはより良い方法

編集 - 以下にソリューションを追加: Hadley の提案と Tommy のナッジを使用して、このようなソリューションを実装しました。

files.to.read <- list.files(datafolder, pattern="\\_D.csv$", full.names=FALSE)
mylist <- llply(files.to.read, read.csv)
all <- do.call("rbind", mylist)
all$id <- rep(files.to.read, sapply(mylist, nrow))

各データフレームの ID として files.to.read ベクトルを使用しました

また、何らかの理由で非常に遅いため、merge_recurse() の使用から変更しました。

 all <- merge_recurse(mylist)

みんな、ありがとう。

4

4 に答える 4

19

個人的には、折りたたみ後に名前を追加する方が簡単だと思います:

df1 <- data.frame(x=c(1:5),y=c(11:15))
df2 <- data.frame(x=c(1:5),y=c(11:15))
mylist <- list(df1 = df1, df2 = df2)

all <- do.call("rbind", mylist)
all$id <- rep(names(mylist), sapply(mylist, nrow))
于 2011-08-16T18:18:44.297 に答える
8

あなたの最初の試みは非常に近かった。値の代わりにインデックスを使用することで機能します。リスト内の要素に名前を付けなかったため、2回目の試行は失敗しました。

以下の両方のソリューションはlapply、関数に追加のパラメーター(mylist)を渡すことができるという事実を使用しています。

df1 <- data.frame(x=c(1:5),y=c(11:15))
df2 <- data.frame(x=c(1:5),y=c(11:15))
mylist <- list(df1=df1,df2=df2) # Name each data.frame!
# names(mylist) <- c("df1", "df2") # Alternative way of naming...

# Use indices - and pass in mylist
mylist1 <- lapply(seq_along(mylist), 
        function(i, x){
            x[[i]]$id <- i
            return (x[[i]])
        }, mylist
)

# Now the names work - but I pass in mylist instead of using portfolio.results.
mylist2 <- lapply(names(mylist), 
    function(n, x){
        x[[n]]$id <- n
        return (x[[n]])
    }, mylist
)
于 2011-08-16T05:46:01.607 に答える
2

names()名前があればうまくいくかもしれませんが、何も与えませんでした。名前のないリストです。数値インデックスを使用する必要があります。

> for(i in 1:length(mylist) ){ mylist[[i]] <- cbind(mylist[[i]], id=rep(i, nrow(mylist[[i]]) ) ) }
> mylist
[[1]]
  x  y id
1 1 11  1
2 2 12  1
3 3 13  1
4 4 14  1
5 5 15  1

[[2]]
  x  y id
1 1 11  2
2 2 12  2
3 3 13  2
4 4 14  2
5 5 15  2
于 2011-08-16T05:37:57.197 に答える
1

dlply関数フォームplyrパッケージが答えになる可能性があります。

library('plyr')
df1 <- data.frame(x=c(1:5),y=c(11:15))
df2 <- data.frame(x=c(1:5),y=c(11:15))
mylist <- list(df1 = df1, df2 = df2)

all <- ldply(mylist)
于 2014-11-09T13:34:32.090 に答える