2017-07-28 118 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)) 
}}