如何更改data.frame中值的比例

时间:2017-05-15 13:06:14

标签: r dataframe

我试图找出如何根据特定比例更改data.frame中的值。这是data.frame中值的示例,其中类值(具有不同的计数)按字段分组" id":

> head(pts)
     id   class
1    245   10
2    522   10
3    522   10
4    522   10

这是比例的一个例子:

id  class   perc%
245   10    100
522   10    50
522   20    50

我的目标是能够为每个" id"选择值。并根据" perc%"更改它们。场,例如如果我有id = 522的100个值,则将50个值更改为class = 10,然后将50个值更改为class = 20(perc%= 50)。

我已尝试对data.frame进行子集化或进行条件选择,但无法找到基本上加入" perc%"的方法。每个" id"的值计数。

提前致谢。

1 个答案:

答案 0 :(得分:0)

我想我现在看到你想要做的更好,这段代码可能不是很优雅,但应该完成工作。 “百分比”数据框表示您描述的第二个表,请注意我将“perc%”重命名为“perc”

colnames(df.percentages) <- c("id","class","perc")

p.check <- df.percentages %>% group_by(id) %>% summarize(sum(perc))
colnames(p.check) <- c("id","sumperc")

not100 <- which(p.check$sumperc != 100)
if(length(not100) != 0)
{
  print(paste("ID",p.check$id[not100],"does not add up to 100%"))
}
rm(p.check)


ids <- unique(df.percentages$id)

for(i in 1:length(ids))
{
  print("")
  print(paste("Processing ID:",ids[i]))
  classes.to.reassign <- pts %>% filter(id == ids[i])
  if(nrow(classes.to.reassign) == 0)
  {
    print(paste("Could not find ID",ids[i],"pts dataframe!"))
    next
  }

  class.rows <- df.percentages %>% 
                filter(id == ids[i]) %>%
                mutate(rows = as.integer(round(nrow(classes.to.reassign) * (perc / 100))))

  if(nrow(classes.to.reassign) < nrow(class.rows))
  {
    print(paste("Cannot split", nrow(classes.to.reassign), "classes into", nrow(class.rows), "segments for ID:", ids[i]))
    next
  }

  if(sum(class.rows$rows) > nrow(classes.to.reassign))
    {class.rows$rows[nrow(class.rows)] <- class.rows$rows[nrow(class.rows)] + (nrow(classes.to.reassign) - sum(class.rows$rows))}
  else if(sum(class.rows$rows) < nrow(classes.to.reassign))
    {class.rows$rows[nrow(class.rows)] <- class.rows$rows[nrow(class.rows)] + (sum(class.rows$rows) - nrow(classes.to.reassign))}

  class.rows <- class.rows %>%
                mutate(cumrows = cumsum(as.integer(rows)))

  print(paste("Total rows for ID",ids[i],"=",nrow(classes.to.reassign)))

  cur.row <- 1
  for(c in 1:nrow(class.rows))
  {
    last.row <- class.rows$cumrow[c]
    print(paste("Assigning class",class.rows$class[c],"to rows",cur.row,"-",last.row))
    classes.to.reassign$class[cur.row:last.row] <- class.rows$class[c]
    cur.row <- last.row + 1
  }

  if(i == 1)
  {pts.new <- classes.to.reassign}
  else
  {pts.new <- rbind(pts.new, classes.to.reassign)}

  rm(classes.to.reassign, class.rows)

}

pts <- pts.new

View(pts)