2017-07-28 120 views
0

我遇到了部分代碼的麻煩。我是一個初學者,我試圖做一個for循環與列表來構造不同的data.frame。讓我們來看看在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

只是'過濾器(nrow,split(df,list(df $ col1,df $ col2)))'應該足夠了 – Sotos

回答

0

這是你所追求的?確保關閉括號並在分配功能上提示。

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)"))), ]) 
} 

如果你的目標是執行對這些不同組的數據進行操作,您可能需要查看包dplyr的包group_by(),該包提供了更簡潔的方式來執行分組操作。

另外,更清潔,方式做到這一點是使用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)) 
}}