我想从“汇总”的数据框中创建一个新的数据框。 以下是我总结的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
很乐意提供帮助
答案 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
运算符
%>%