从汇总的df创建原始选择数据框

时间:2017-03-14 08:05:18

标签: r dataframe

我想从“汇总”的数据框中创建一个新的数据框。 以下是我总结的df的简化示例:

vehicle <- c("bike", "car", "bus")
size <- c(1,2,3)
color <- c("green", "red", "blue")
price <- c(100,200,10)
n <- c(3,2,1)

my.df <- data.frame(vehicle,size,color,price,n)

 my.df    
  vehicle size color price n
1    bike    1 green   100 3
2     car    2   red   200 2
3     bus    3  blue    10 1

现在,想象一下这些数据是根据人们对车辆的选择进行总结的。 选择车辆的次数在第n栏中列出。 现在我想制作一个原始的“选择数据集”,其中添加了一列响应者ID。新列选择表示已选择的替代项(表示来自my.df的n列)

我希望新数据框my.new.df看起来像:

respondent <- c(1.1,1.2,1.3,2.1,2.2,2.3,3.1,3.2,3.1,4.1,4.2,4.3,5.1,5.2,5.3,6.1,6.2,6.3)
vehicle.2 <- rep(vehicle,6)
size.2 <- rep(size,6)
color.2 <- rep(color,6)
price.2 <- rep(price,6)
choice <- c(0,0,1,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0)

my.new.df <- data.frame(respondent, vehicle.2 ,size.2,color.2,price.2,choice)


 my.new.df
   respondent vehicle.2 size.2 color.2 price.2 choice
1         1.1      bike      1   green     100      0
2         1.2       car      2     red     200      0
3         1.3       bus      3    blue      10      1
4         2.1      bike      1   green     100      0
5         2.2       car      2     red     200      1
6         2.3       bus      3    blue      10      0
7         3.1      bike      1   green     100      1
8         3.2       car      2     red     200      0
9         3.1       bus      3    blue      10      0
10        4.1      bike      1   green     100      1
11        4.2       car      2     red     200      0
12        4.3       bus      3    blue      10      0
13        5.1      bike      1   green     100      0
14        5.2       car      2     red     200      1
15        5.3       bus      3    blue      10      0
16        6.1      bike      1   green     100      1
17        6.2       car      2     red     200      0
18        6.3       bus      3    blue      10      0

很乐意提供帮助

2 个答案:

答案 0 :(得分:2)

使用dplyr我们可以为每一行创建一个新的n * 3 data.frame并将它们粘在一起。我们必须使用paste来获取受访者ID(尽管我认为他们应该只是c(1, 1, 1, 2, 2, 2, ...))。

my.df %>% 
  rowwise() %>%                                                  #we need to do this by row
  do( {
    d <- mutate(my.df, choice = as.numeric(vehicle == .$vehicle))#add choice column
    d[rep(seq_len(nrow(d)), .$n), ]                              #repeat n times
    } ) %>% 
  ungroup() %>%                                                  #drop the groups
  mutate(respondent = paste(rep(1 : (n() / 3), each = 3),        #add in the weird ids
                            rep(1:3, n() / 3),
                            sep = '.')) %>% 
  select(-n)                                                     #drop the n column

我的结果看起来不一样,因为你的结果似乎是自下而上构建的(即你从公共汽车开始,即使my.df以自行车开始)。

# A tibble: 18 × 6
   vehicle  size  color price choice respondent
    <fctr> <dbl> <fctr> <dbl>  <dbl>      <chr>
1     bike     1  green   100      1        1.1
2      car     2    red   200      0        1.2
3      bus     3   blue    10      0        1.3
4     bike     1  green   100      1        2.1
5      car     2    red   200      0        2.2
6      bus     3   blue    10      0        2.3
7     bike     1  green   100      1        3.1
8      car     2    red   200      0        3.2
9      bus     3   blue    10      0        3.3
10    bike     1  green   100      0        4.1
11     car     2    red   200      1        4.2
12     bus     3   blue    10      0        4.3
13    bike     1  green   100      0        5.1
14     car     2    red   200      1        5.2
15     bus     3   blue    10      0        5.3
16    bike     1  green   100      0        6.1
17     car     2    red   200      0        6.2
18     bus     3   blue    10      1        6.3

答案 1 :(得分:1)

Axeman的答案很棒。使用plyr

的另一种解决方案
obs <- ddply(my.df,.(vehicle),function(df){df[rep(row.names(df),df$n),1:4]})
res <- adply(obs, 1, function(df) {
    data.frame(
      respondent = paste(rownames(df), 1:3, sep = '.'),
      my.df[,1:4],
      choice = as.numeric(my.df$vehicle == df$vehicle))})

您可以使用obs运算符

删除%>%