【问题标题】:Split dataframe in R在 R 中拆分数据框
【发布时间】:2019-09-23 17:09:35
【问题描述】:

我有一个这样的数据集

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 .......
......................

现在我想将此数据集拆分为更多观察值,这取决于像 number

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 
 .......

或者只要条件不成立,同样重复观察。

如何拆分无关紧要,但对于您为其他变量拆分的数据,观察结果必须相同?

【问题讨论】:

  • 不清楚你是如何从第一个块到第二个块的。您能否使您的示例具有可重复性以及预期的结果应该是什么?请展示您迄今为止在算法和编码方面的尝试。
  • 如果数字大于 20,我只想将行拆分为重复行。行看起来如何并不重要。因此,您将第一个以 10 作为数字分成两行,或者您可以将它们分成 3 行,分别为 8、9、3 等等。但其余变量必须相同。 a 必须是您拆分的行,例如在两个新行中。

标签: r dataframe split


【解决方案1】:
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

【讨论】:

    【解决方案2】:

    我们可以通过多种方式拆分一个数字 >=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。只要存在编号 >=20 的行,while 循环就会重复调用 doSplit() 函数。

    > 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多