无法更新数据框中的数据

时间:2018-05-02 15:22:08

标签: r dataframe

我尝试更新数据框中的数据,但无法更新

//在此初始化数据和数据框

    user_data=read.csv("train_5.csv")
    baskets.df=data.frame(Sequence=character(),
                          Challenge=character(), 
                          countno=integer(), 
                          stringsAsFactors=FALSE) 

/更新数据框中的数据

for(i in 1:length((user_data)))
{
  for(j in i:length(user_data))
  {
    if(user_data$challenge_sequence[i]==user_data$challenge_sequence[j]&&user_data$challenge[i]==user_data$challenge[j])
    {
     writedata(user_data$challenge_sequence[i],user_data$challenge[i])

    }

  }

}
writedata=function( seqnn,challng)
{

  #print(seqnn)
  #print(challng)
  newRow <- data.frame(Sequence=seqnn,Challenge=challng,countno=1)
  baskets.df=rbind(baskets.df,newRow)

}

//在此处查看数据

View(baskets.df)

2 个答案:

答案 0 :(得分:0)

我已将您的代码修改为我认为可行的代码。您尚未提供示例数据,因此我无法验证它是否按您希望的方式工作。我在这里尝试了几个常见的新手错误,我会尽力解释。

您的writedata函数的编写范围有点宽松。当您创建一个新函数时,该函数中发生的事情在技术上发生在它自己的环境中。也就是说,它尝试查找函数中定义的内容,然后创建的任何新对象仅在该环境中创建。 R也有这个整洁(有时很棘手)的功能,如果它在环境中找不到对象,它将尝试查看父环境。

这对您的writedata函数产生的影响是,当R在函数中查找baskets.df但找不到它时,R然后转向全局环境,找到baskets.df在那里,然后在rbind中使用它。但是,rbind的结果会保存到 function 环境中的baskets.df,并且不会在全局环境中更新同名对象。

为了解决这个问题,我在writedata添加了一个名为data的参数。然后我们可以使用此参数将数据框传递给函数的环境并在本地执行所有操作。通过不在最后进行任何赋值,我们隐含地告诉函数返回它的结果。

然后,在您的循环中,我们不是简单地调用writedata,而是将其结果分配回baskets.df以替换之前的结果。

for(i in 1:length((user_data)))
{
  for(j in i:length(user_data))
  {
    if(user_data$challenge_sequence[i] == user_data$challenge_sequence[j] && 
       user_data$challenge[i] == user_data$challenge[j])
    {
     baskets.df <- writedata(baskets.df, 
                             user_data$challenge_sequence[i],
                             user_data$challenge[i])

    }

  }

}


writedata=function(data, seqnn,challng)
{

  #print(seqnn)
  #print(challng)
  newRow <- data.frame(Sequence = seqnn,
                       Challenge = challng,
                       countno = 1)
  rbind(data, newRow)

}

答案 1 :(得分:0)

我不确定你的编程背景是什么,但是你的循环在R中会非常慢,因为它是一种解释语言。为了解决这个问题,许多函数都是矢量化的(这意味着你给它们提供了多个数据点,并且它们在循环快速的编译代码中进行循环)。

考虑到这一点,我相信这将是一个更快的代码实现

user_data=read.csv("train_5.csv")

# challenge_indices will be a matrix with TRUE at every place "challenge" and "challenge_sequence" is the same
challenge_indices <- outer(user_data$challenge_sequence, user_data$challenge_sequence, "==") &
  outer(user_data$challenge, user_data$challenge, "==")

# since you don't want duplicates, get rid of them
challenge_indices[upper.tri(challenge_indices, diag = TRUE)] <- FALSE

# now let's get the indices of interest
index_list <- which(challenge_indices,arr.ind = TRUE)

# now we make the resulting data set all at once
# this is much faster, because it does not require copying the data frame many times - which would be required if you created a new row every time.
baskets.df <- with(user_data, data.frame(
  Sequence = challenge_sequence[index_list[,"row"]],
  challenge = challenge[index_list[,"row"]]
)