通过重复行来转换数据框并创建一个变量来计算两个变量的值

Transform dataframe by repeating rows and create a variable counting values of two variables

这是数据的一小部分:

我有:

df 

ID numberPOS numberNEG
 1         2         3
 2         5         4
 3         1         2

我的愿望是用一个新变量 statut 来转换数据帧,计算负数和正数的次数,并为每个 ID 重复行,如下所示:

df
ID numberPOS numberNEG statut
1          2         3    POS
1          2         3    POS
1          2         3    NEG
1          2         3    NEG
1          2         3    NEG
2          5         4    POS
2          5         4    POS
2          5         4    POS
2          5         4    POS
2          5         4    POS
2          5         4    NEG
2          5         4    NEG
2          5         4    NEG
2          5         4    NEG
3          1         2    POS
3          1         2    NEG
3          1         2    NEG

所以第一行重复了 5 次,因为 numberPOS + numberNEG = 2 + 3 = 5。 我想为每一行创建变量 statut 2 次 POS 和 3 次 NEG。 有人看到这个问题吗? 帮助将不胜感激。 谢谢

我们可以在根据'numberPOS'、'numberNEG'

中的值创建'statut'之后使用unnest
library(dplyr)
library(tidyr)
df %>% 
   mutate(statut = map2(numberPOS, numberNEG,
         ~ rep(c('POS', 'NEG'), c(.x, .y)))) %>% 
    unnest(c(statut))

-输出

# A tibble: 17 x 4
#      ID numberPOS numberNEG statut
#   <int>     <int>     <int> <chr> 
# 1     1         2         3 POS   
# 2     1         2         3 POS   
# 3     1         2         3 NEG   
# 4     1         2         3 NEG   
# 5     1         2         3 NEG   
# 6     2         5         4 POS   
# 7     2         5         4 POS   
# 8     2         5         4 POS   
# 9     2         5         4 POS   
#10     2         5         4 POS   
#11     2         5         4 NEG   
#12     2         5         4 NEG   
#13     2         5         4 NEG   
#14     2         5         4 NEG   
#15     3         1         2 POS   
#16     3         1         2 NEG   
#17     3         1         2 NEG   

uncountrep

的另一个选项
df %>%
   uncount(numberPOS + numberNEG) %>% 
   mutate(statut = rep(rep(c("POS", "NEG"), nrow(df)), c(t(df[-1]))))

数据

df <- structure(list(ID = 1:3, numberPOS = c(2L, 5L, 1L), numberNEG = c(3L, 
4L, 2L)), class = "data.frame", row.names = c(NA, -3L))

仅使用 base 包,解决方案可能是这样的:

df <- data.frame(ID=c(1,2,3),numberPOS=c(2,5,1),numberNEG=c(3,4,2))

do.call("rbind",lapply(df$ID, function(id) {
  fittingRowIndex <- df$ID==id
  fittingRow <- df[fittingRowIndex,]
  newDf <- fittingRow[rep(1,fittingRow$numberPOS+fittingRow$numberNEG),]
  newDf$statut <- rep(c("POS","NEG"),times=c(fittingRow$numberPOS,fittingRow$numberNEG))
  newDf
}))