использование tidyverse для одновременной фильтрации, суммирования и размещения результатов в новом столбце того же фрейма данных в указанной позиции - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь добавить результаты сводной статистики c в таблицу в указанной позиции в другом столбце этой таблицы, после фильтрации всех моих данных для подмножества, которое я хочу обобщить. Он содержит результаты пространственно-явного моделирования в ландшафте ячеек сетки. У меня есть столбец с указанием столбца и строки ландшафта и столбец для результатов. Я хочу взять целевую ячейку сетки, например, row= 2, col =2 и вычислить дисперсию целевой ячейки и ее восьми окружающих ячеек. Результат этого должен быть сохранен в новом столбце кадра данных, в строке целевой ячейки сетки. Фильтрация данных для выбора только девяти патчей, которые меня интересуют, работает нормально, но сохранение результата в новом столбце в указанном месте c не работает. Мне нужно общее решение, так как я хочу l oop через все ячейки сетки (заданные в строке и столбце), а также l oop через несколько столбцов, содержащих сходные данные, но для разных ландшафтов я выкладываю пример кода здесь мой реальный набор данных намного больше.

data= tibble(row=c(1,1,1, 2,2,2, 3,3,3), col=c(1,2,3, 1,2,3, 1,2,3), x=c(0.5, 0.5, 0.5, 0.4, 0.4, 0.4, 0.3, 0.3, 0.3), cluster_var=0)
> data
# A tibble: 9 x 4
    row   col     x cluster_var
  <dbl> <dbl> <dbl>       <dbl>
1     1     1   0.5           0
2     1     2   0.5           0
3     1     3   0.5           0
4     2     1   0.4           0
5     2     2   0.4           0
6     2     3   0.4           0
7     3     1   0.3           0
8     3     2   0.3           0
9     3     3   0.3           0

Допустим, это таблица с моими результатами. Теперь я хочу выбрать целевые ячейки сетки и восемь соседних ячеек, например, row = 2, col = 2, и рассчитать дисперсию x для этих девяти ячеек, поэтому я сделал это:

i_row=2
i_col=2

  data%>%filter(row==(i_row-1) | row == (i_row+1) | row==i_row) %>% 
  filter(col==(i_col-1) | col==(i_col+1) | col==i_col) %>% 
  summarise(var(x))
# A tibble: 1 x 1
  `var(x)`
     <dbl>
1   0.0075

Теперь Я хотел бы сохранить его в data$cluster_var в строке, где row=2 и col=2, поэтому полученный тиббл будет:

> data
# A tibble: 9 x 4
    row   col     x cluster_var
  <dbl> <dbl> <dbl>       <dbl>
1     1     1   0.5           0
2     1     2   0.5           0
3     1     3   0.5           0
4     2     1   0.4           0
5     2     2   0.4           0.0075
6     2     3   0.4           0
7     3     1   0.3           0
8     3     2   0.3           0
9     3     3   0.3           0

Конечно, мне понадобится l oop через все возможные значения row и col, чтобы заполнить весь столбец cluster_var, и реальный набор данных действительно большой, поэтому я не могу сделать это вручную. Я пытался с mutate, но это не сработало, как я хотел.

data%>%
  mutate(., cluster_var[row==i_row, col==i_col] = 
  filter(row==(i_row-1) | row == (i_row+1) | row==i_row) %>% 
  filter(col==(i_col-1) | col==(i_col+1) | col==i_col) %>% 
  summarise(var(x)))
Error: unexpected '=' in "data%>%
  mutate(., cluster_var[row==i_row, col==i_col] ="

В данный момент я в растерянности и буду благодарен за помощь! Изменить: немного больше информации о моих данных: девять записей, которые меня интересуют, не являются последовательными. Когда целевая сетка имеет row= 2 и col= 2, меня могут заинтересовать следующие значения: [2,1], [2,3], [1,1], [2,1], [3,1], [1,3], [2,3], [3,3]. В примерных данных они находятся в последовательных строках, но в моих реальных данных у меня 64 строки и 64 столбца, и значение row равно 1 в первых 64 строках, тогда как col увеличивается с 1:64, затем row=2 и снова col 1:64 и так далее, всего 4096 строк. Таким образом, номер строки результатов, которые я хочу обобщить, не связан со значениями в row или col

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Насколько я понимаю, вы хотите рассчитать дисперсию девяти значений, включая целевое значение ячейки. Решение может быть применено с использованием значения индекса dataframe и уникального ключа для получения целевой ячейки. ниже приведено решение для l oop и dplyr:

df= tibble(row=c(1,1,1, 2,2,2, 3,3,3), col=c(1,2,3, 1,2,3, 1,2,3), x=c(0.5, 0.5, 0.5, 0.4, 0.4, 0.4, 0.3, 0.3, 0.3), cluster_var=0)
l<-c() # empty vector which will be used for stroing variance value
df$RowNumber<- row.names(df) # getting index of row
df$key<-paste0(df$row,",",df$col) # generating key

keyList<- unique(df$key) #list all unique values of key , over this loop will run

for(i in 1:length(keyList)){

  #cat("Running For:",i,'\n')
  rowIndx <- df %>% 
        filter(key==keyList[i]) %>% 
        select(RowNumber) %>%
        as.numeric()

  filterValues <-seq((rowIndx-4):(rowIndx+4)) # getting index for 9 values including target cell

 l[i]<- df %>% 
    filter(RowNumber %in% filterValues) %>% 
     summarise(.,cluster_var =  var(x))

}

df$cluster_var<- unlist(l) # adding calculated variance to data frame

Это решение может быть не оптимальным.

0 голосов
/ 08 мая 2020

Я нашел решение, которое должно работать для большинства целей здесь. Это не только в Tidyverse, но делает работу. Следующий код делает то, что я хочу:

data=tibble(row=c(1,1,1, 2,2,2, 3,3,3), col=c(1,2,3, 1,2,3, 1,2,3), x=c(0.5, 0.5, 0.5, 0.4, 0.4, 0.4, 0.3, 0.3, 0.3))
cluster_var=numeric(nrow(data))

for(i in 1:max(data$row)){
  for(j in 1:max(data$col)){
    i_row=i
    i_col=j
    position=which(data$row==i_row & data$col==i_col)
    cluster_var_temp= as.numeric(data%>%
                                   filter(row==(i_row-1) | row == (i_row+1) | row==i_row) %>% 
                                   filter(col==(i_col-1) | col==(i_col+1) | col==i_col) %>% 
                                   summarise(var(x)))
    cluster_var[position]=cluster_var_temp

  }

} 

data=cbind(data, cluster_var)

> data
  row col   x cluster_var
1   1   1 0.5 0.003333333
2   1   2 0.5 0.003000000
3   1   3 0.5 0.003333333
4   2   1 0.4 0.008000000
5   2   2 0.4 0.007500000
6   2   3 0.4 0.008000000
7   3   1 0.3 0.003333333
8   3   2 0.3 0.003000000
9   3   3 0.3 0.003333333

Спасибо всем за помощь! @Nirbhay Сингх, ты поставил меня в правильном направлении. И, возможно, это поможет людям, которые ищут это или что-то подобное в будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...