Зацикливание или применение для суммы значений R-данных на основе нескольких условий, удовлетворяющих внешним переменным - PullRequest
0 голосов
/ 01 октября 2018

У меня есть начальный фрейм данных, который выглядит примерно так, как показано ниже.Тот же базовый формат (заголовки, все соответствующие значения являются числовыми. Та же самая черта, что Time.Start и Time.End имеют меньшее количество уникальных значений

 #df1
     Time.Start  Time.End   Lead   Result   Count
  [1]         1         0      1        1       1
  [2]         2         1      1       .5       1
  [3]         1         0      1        1       1
  [4]         3         1      1        0       1
  [5]         6         2      2        1       1
  [6]         4         3      2        0       1
  [7]         5         2      1        1       1
  [8]         3         1      1        0       1
  [9]         3         2      2        1       1
 [10]         2         0      2        1       1
 [11]         7         2      1        0       1
 [12]         2         1      1       .5       1
 [13]         9         0      2        1       1
 [14]         0         0      2        1       1         
 [15]         8         3      1       .5       1

Я хочу взять эти значения и поместить их в кадр данных илиматрица, которая выглядит следующим образом.

Time <- 0:10
#df2
Time                                                                  Lead.1 
   0   sum(Result)/sum(Count) at df$Lead=1 df$Time.Start>=0 & df$Time.End<=0         
   1   sum(Result)/sum(Count) at df$Lead=1 df$Time.Start>=1 & df$Time.End<=1
   2   sum(Result)/sum(Count) at df$Lead=1 df$Time.Start>=2 & df$Time.End<=2
 ...                                                                     ...
  10 sum(Result)/sum(Count) at df$Lead=1 df$Time.Start>=10 & df$Time.End<=10

Хитрость в том, что я не могу просто найти каждую точку, где время равно Time.Start или Time.End, мне также нужна каждая точка, где время находится между илисоответствует строке Time.Start или Time.End. Поэтому для Time = 2 из примера df я бы хотел получить сумму значений в строках, 2, 4, 5, 7, 8, 9, 10, 11 и 12.Для каждого отдельного значения отведения будет создан отдельный вектор, причем все отведения из 4 или более будут объединены в один

. Если бы я захотел сгенерировать это вручную, я мог бы. Формула ниже может быть использована для нахожденияэто в любое время и для любого отведения.

sum(df[df$Lead==1 & df$Time.End<=t & df$Time.Start>=t,"Result")]/ 
sum(df[df$Lead==1 & df$Time.End<=t & df$Time.Start>=t,"Count")]

Это не практичное решение, поскольку фактический набор данных имеет 300 различных значений времени, а не 11. Сначала я попытался создать цикл for

    Lead1 <- for(i in Time){ 
          sum(df$Lead.Group=="1" & df[df$Time.End<=i & df$Time.Start>=i,"Result"])/
          sum(df$Lead.Group=="1" & df[df$Time.End<=i & df$Time.Start>=i,"Count"])
   }

Это тольковыведите пару сотен сообщений об ошибке «длина объекта не кратна длине объекта».Я получил те же результаты при использовании функции by ().

Если уместно, цель после генерации второго кадра данных состоит в том, чтобы создать диаграмму рассеяния из каждого значения отведений, изменяющегося со временем.Это должно быть довольно легко управляемо с ggplot2

1 Ответ

0 голосов
/ 01 октября 2018

Попробуйте снова запустить by, чтобы разрезать фрейм данных по Lead группам и построить список векторов, который вычисляет ваши суммарные отношения по последовательности Time .Из полученного списка объектов запустите do.call(cbind, ...), чтобы объединить все векторы для окончательного вывода матрицы:

Данные

txt <- 'Time.Start  Time.End   Lead   Result   Count
  1         0      1        1       1
  2         1      1       .5       1
  1         0      1        1       1
  3         1      1        0       1
  6         2      2        1       1
  4         3      2        0       1
  5         2      1        1       1
  3         1      1        0       1
  3         2      2        1       1
  2         0      2        1       1
  7         2      1        0       1
  2         1      1       .5       1
  9         0      2        1       1
  0         0      2        1       1         
  8         3      1       .5       1'

df1 <- read.table(text=txt, header=TRUE)
df1

Код

Time <- 0:10

mat_list <- by(df1, df1$Lead, function(sub){
  # CURRENT LEAD NAME
  leadcol <- paste0("Lead.", sub$Lead[[1]])  

  # BUILD NAMED NUMERIC VECTOR ACROSS TIME
  vec_list <- lapply(Time, function(t) {
    mask <- sub$Time.Start >= t & sub$Time.End <= t
    setNames(sum(sub[mask,"Result"])/sum(sub[mask, "Count"]), leadcol)
  })
  do.call(rbind, vec_list)
})

# BUILD MASTER MATRIX
final_mat <- cbind(Time, do.call(cbind, mat_list))
final_mat

#       Time    Lead.1    Lead.2
#  [1,]    0 1.0000000 1.0000000
#  [2,]    1 0.5000000 1.0000000
#  [3,]    2 0.3333333 1.0000000
#  [4,]    3 0.3000000 0.7500000
#  [5,]    4 0.5000000 0.6666667
#  [6,]    5 0.5000000 1.0000000
#  [7,]    6 0.2500000 1.0000000
#  [8,]    7 0.2500000 1.0000000
#  [9,]    8 0.5000000 1.0000000
# [10,]    9       NaN 1.0000000
# [11,]   10       NaN       NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...