R разделить фрейм данных - PullRequest
       11

R разделить фрейм данных

0 голосов
/ 23 сентября 2019

У меня есть такой набор данных

alpha number  fr color
1     a   20 0.8   rot
2     a   21 2.0   rot
3     a    2 0.8   rot
4     a   34 0.8   rot
5     f   42 0.5  grün .......
......................

Теперь я хочу разделить этот набор данных на большее количество наблюдений, которое зависит от условия типа <20, чтобы новый набор данных выглядел как </p>

alpha number  fr color
1     a   19 0.8   rot
2     a   1  0.8   rot
3     a   10 2.0   rot
4     a   11 2.0   rot
5     a    2 0.8   rot
6     a   19 0.8   rot
7     a   15 0.8   rot
8     f   7  0.5  grün 
9     f   7  0.5  grün 
10     f   7  0.5  grün 
11    f   7  0.5  grün 
12     f   7  0.5  grün 
13    f   7  0.5  grün 
 .......

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

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Во многих случаях мы могли бы разбить число> = 20, но метод ниже делит каждое число пополам, то есть четные числа (m = 2n) делятся на n и n, нечетные числа (m = 2n + 1) делятся на(n + 1) и n.

> library(dplyr)
> df <- data.frame(alpha=c("a","a","a","a","f"),
+                  number=c(20,21,2,34,42),
+                  fr=c(0.8,2.0,0.8,0.8,0.5),
+                  color=c("rot","rot","rot","rot","grün"))

Функция doSplit() принимает в качестве аргумента фрейм данных df и целое число threshold.

> doSplit <- function(df, threshold){
+   # splits rows where number >= threshold until all rows have number < threshold
+   
+   colNames <- colnames(df)
+   df <- df %>% mutate(orig_id=rownames(df))
+   dfBelow <- df %>% filter(number<threshold)
+   dfAbove1 <- df %>% filter(number>=threshold) %>% mutate(number=(number%/%2)+(number%%2))
+   dfAbove2 <- df %>% filter(number>=threshold) %>% mutate(number=number%/%2)
+   combData <- rbind(dfBelow, dfAbove1, dfAbove2)
+   combData <- combData %>% arrange(orig_id) %>% select(colNames)
+   return(combData)  
+ }

Здесь мы определяемпорог 20. Цикл while многократно вызывает функцию doSplit(), пока существует строка с номером> = 20.

> myThreshold <- 20
> splitDf <- df
> while(splitDf %>% pull(number) %>% max() >= myThreshold){
+     splitDf <- doSplit(splitDf, myThreshold)
+ }

Вот разделенный фрейм данных:

> splitDf
   alpha number  fr color
1      a     10 0.8   rot
2      a     10 0.8   rot
3      a     11 2.0   rot
4      a     10 2.0   rot
5      a      2 0.8   rot
6      a     17 0.8   rot
7      a     17 0.8   rot
8      f     11 0.5  grün
9      f     10 0.5  grün
10     f     11 0.5  grün
11     f     10 0.5  grün
0 голосов
/ 23 сентября 2019
df1 <- structure(list(alpha = c("a", "a", "a", "a", "f"), 
                      number = c(20L, 21L, 2L, 34L, 42L), 
                      fr = c(0.8, 2, 0.8, 0.8, 0.5), 
                      color = c("rot", "rot", "rot", "rot", "grun")), 
                 row.names = c(NA, -5L), class = "data.frame")
rep.rev <- function(x,t){
  if(t != 0){
    rep(x,t)
  } else {
    NA_integer_
  }
}
library(dplyr)
library(tidyr)
set.seed(22)
df1 %>% 
  mutate(divisor = floor(runif(n(), min = 2, max = 19)),
         quotient = number%/%divisor,
         remainder = ifelse(number%%divisor==0, NA, number%%divisor)) %>% 
  rowwise %>% 
  mutate(number = list(c(rep.rev(divisor, quotient),remainder))) %>% 
  unnest %>% 
  select(alpha, number, fr, color) %>% 
  filter(!is.na(number))
#> # A tibble: 14 x 4
#>    alpha number    fr color
#>    <chr>  <dbl> <dbl> <chr>
#>  1 a          7   0.8 rot  
#>  2 a          7   0.8 rot  
#>  3 a          6   0.8 rot  
#>  4 a         10   2   rot  
#>  5 a         10   2   rot  
#>  6 a          1   2   rot  
#>  7 a          2   0.8 rot  
#>  8 a         10   0.8 rot  
#>  9 a         10   0.8 rot  
#> 10 a         10   0.8 rot  
#> 11 a          4   0.8 rot  
#> 12 f         16   0.5 grun 
#> 13 f         16   0.5 grun 
#> 14 f         10   0.5 grun
...