在for循环中使用list

时间:2017-07-28 13:05:25

标签: r for-loop

我遇到了部分代码问题。我是一名初学者,我尝试使用列表创建一个for循环来构建不同的data.frame。我们来看看

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))

在这种情况下,目标是使用我的原始数据框构建不同的数据框。在这种情况下,它可能看起来有点棘手,但即使语法相似,我也没有使用这种方式。

问题在于数据框的粘贴名称和&#34; $&#34;的附加功能。 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

您有解决此问题的想法吗?

3 个答案:

答案 0 :(得分:1)

如果我正确地解释了问题,为了完全按照您的需要做,您需要evalparsedf <- 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()&#39; split(),它提供了一种更清晰的方式来执行分组操作

另一种更清洁的方法是使用split_dfs <- split(df, df$col1) split_dfs <- lapply(split_dfs, function(x) split(x, x$col2)) 函数将每个拆分存储在一个列表中:

object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        var queryDictionary = HttpUtility.ParseQueryString(request.Headers.To.Query);
        string parameterValue = queryDictionary[this.BehaviourConfiguration.QueryParameter];

        //Only change parameter value if it exists
        if (parameterValue != null)
        {
            MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);

            request = buffer.CreateMessage();

            //Necessary in order to read the message without having WCF throwing and error saying
            //the messas was already read
            var reqAux = buffer.CreateMessage();

            //For some reason the message comes in binary inside tags <Binary>MESSAGE</Binary>
            using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(reqAux.ToString().Replace("<Binary>", "").Replace("</Binary>", ""))))
            {
                ms.Position = 0;
                string val = ExtractNodeValueByXPath(ms, this.BehaviourConfiguration.FieldXpath);

                queryDictionary.Set(this.BehaviourConfiguration.QueryParameter, DateTime.Now.ToString("yyyyMMddHHmmssfff") + "_" +
                    this.BehaviourConfiguration.Message + (string.IsNullOrWhiteSpace(val) ? string.Empty : "_" + val) + ".xml");

                UriBuilder ub = new UriBuilder(request.Headers.To);
                ub.Query = queryDictionary.ToString();
                request.Headers.To = ub.Uri;
            }
        }

        return null;
    }

答案 1 :(得分: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) )
}}

答案 2 :(得分: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),])
  }