2017-07-28 19 views
0

私のコードの一部に問題があります。私は初心者ですし、別のdata.frameを作成するためにリストを使ってforループを作成しようとしました。みましょうforループのリストの使用

df<-data 

head(data) 

col1 col2 col3 
A  1  13 
A  2  34 
A  2  46 
B  1  23 
D  3  56 
B  2  31 


df_a<-data[which(data$col1=="A") 
df_b<-data[which(data$col1=="B") 
df_c<-data[which(data$col1=="C") 
df_d<-data[which(data$col1=="D") 

list<-c("_a","_b","_c","_d") 
for (i in list){ 
    paste0("df",i,"1")<-data(which(paste0("df",i)$col2==1)) 
    paste0("df",i,"2")<-data(which(paste0("df",i)$col2==2)) 
    paste0("df",i,"3")<-data(which(paste0("df",i)$col2==3)) 

この場合、私の元のデータフレームとは異なるデータフレームを構築することです。この文脈ではちょっと厄介なように見えるかもしれませんが、たとえ構文が似ていても、私はこの方法をまったく使っていません。

問題は、データフレームのペースト名と "$"の補助によるものです。 Rはエラーメッセージを返す:

Error in which(paste0("df", i, "1")$col2 == 1) : 
    erreur d'évaluation de l'argument 'x' lors de la sélection d'une 
méthode pour la fonction 'which' : Error in paste0("df", 
i, "1")$col2 : 
    $ operator is invalid for atomic vectors 

をあなたはこの問題を解決するためのアイデアを持っていますか?

+1

、それがあるべき'df_a <-data [which(data $ col1 ==" A ")、]'のようなもので、b、c、dについても同様です。 – jdb

+0

'Filter(nrow、split(df、list(df $ col1、df $ col2)))')は十分でなければなりません – Sotos

答えて

0

これはあなたが何をしているのですか?あなたの括弧を閉じて、assign関数を手がかりにしてください。

col1 = c("A","A","A","B","D","B") 
col2 = c(1,2,2,1,3,2) 
col3 = c(13,34,46,34,56,31) 

data = cbind(col1,col2,col3) 
data = as.data.frame(data) 


list<-c("_a","_b","_c","_d") 

for (i in list){ 
    assign(paste0("df",i,"1"),data[which(data$col1 =="A" & data$col2 ==1),]) 
    assign(paste0("df",i,"2"),data[which(data$col1 =="B" & data$col2 ==2),]) 
    assign(paste0("df",i,"3"),data[which(data$col1 =="C" & data$col2 ==3),]) 
    } 
1

私はあなたが正確に必要なものを行うためには、正しく質問を解釈していた場合は、assignの組み合わせ、eval、およびparseを必要とする:

df <- data.frame(col1 = c("A", "A", "A", "B", "D", "B"), 
       col2 = c(1, 2, 2, 1, 3, 2), 
       col3 = c(13 ,34, 46, 23, 56, 31)) 

df_a<-df[which(df$col1=="A"), ] 
df_b<-df[which(df$col1=="B"), ] 
df_c<-df[which(df$col1=="C"), ] 
df_d<-df[which(df$col1=="D"), ] 

list <- c("_a","_b","_c","_d") 

for (i in list) { 
    assign(paste0("df", i, "1"), df[eval(parse(text = paste0("which(df", i, "$col2 == 1)"))), ]) 
    assign(paste0("df", i, "2"), df[eval(parse(text = paste0("which(df", i, "$col2 == 2)"))), ]) 
    assign(paste0("df", i, "3"), df[eval(parse(text = paste0("which(df", i, "$col2 == 3)"))), ]) 
} 

あなたの目標は実行している場合これらの異なるグループのデータを操作する場合は、パッケージdplyrgroup_by()を調べると、グループ化された操作をよりきれいに行うことができます。これを行うには

別の、よりクリーン、方法が1つのリストに分割のそれぞれを格納するsplit()機能を使用している:あなたはあなたのコードで閉じ括弧が欠落している

split_dfs <- split(df, df$col1) 
split_dfs <- lapply(split_dfs, function(x) split(x, x$col2)) 
+0

みなさん、ありがとう。この解決策は問題を解決する!そして、はい、最後の提案は明らかに私のものよりきれいです...私はこの機能を次回思い出すでしょう –

1
df <- read.table(text="col1 col2 col3 
A  1  13 
A  2  34 
A  2  46 
B  1  23 
D  3  56 
B  2  31", header=T) 



library(dplyr) 
letters <- c("A", "B", "C", "D") 
for(i in 1:3){ 
for(j in seq_along(letters)){ 
    assign(paste0("df_",tolower(letters[j]), i), df %>% filter(col1==letters[j]) %>% select(i)) 
}} 
関連する問題