我有一个简单的数据框,可以说:
dd <- data.frame(id = letters[1:4], v1 = c(0.3,0.1,0.7,1.3))
dd
id v1
1 a 0.3
2 b 0.1
3 c 0.7
4 d 1.3
对于此数据帧的每一行,我想通过添加一个给出数字序列的新变量来“分解”它。我成功完成了此操作,但这是我的代码不理想且几乎没有消耗:
dd %>%
mutate("0"=0,"5"=5,"10"=10) %>%
reshape2::melt(id.vars=c("id", "v1")) %>%
select(-variable)
id v1 value
1 a 0.3 0
2 b 0.1 0
3 c 0.7 0
4 d 1.3 0
5 a 0.3 5
6 b 0.1 5
7 c 0.7 5
8 d 1.3 5
9 a 0.3 10
10 b 0.1 10
11 c 0.7 10
12 d 1.3 10
因此,在此示例中,我为每一行添加了一个名为value
的列,该列在c(0,5,10)
内具有所有三个值
此代码并不理想,因为我想要的实际序列几乎是1:70
,并且我不想手动在我的mutate
中编写所有70个新变量。当然有更好的方法,您能帮我吗?
我不必呆在dplyr
中,但我希望可以通过它传递代码。
谢谢
答案 0 :(得分:3)
library(tidyr)
dd %>% crossing(value = c(0, 5, 10))
id v1 value
1 a 0.3 0
2 a 0.3 5
3 a 0.3 10
4 b 0.1 0
5 b 0.1 5
6 b 0.1 10
7 c 0.7 0
8 c 0.7 5
9 c 0.7 10
10 d 1.3 0
11 d 1.3 5
12 d 1.3 10
答案 1 :(得分:2)
一种选择是在数据框中添加值,并在基数R中执行merge
。
merge(dd, data.frame(value = c(0, 5, 10)))
# id v1 value
#1 a 0.3 0
#2 b 0.1 0
#3 c 0.7 0
#4 d 1.3 0
#5 a 0.3 5
#6 b 0.1 5
#7 c 0.7 5
#8 d 1.3 5
#9 a 0.3 10
#10 b 0.1 10
#11 c 0.7 10
#12 d 1.3 10
答案 2 :(得分:1)
我们还可以使用expand
包中的tidyr
。
library(tidyverse)
dd <- data.frame(id = letters[1:4], v1 = c(0.3,0.1,0.7,1.3))
dd %>%
expand(nesting(id, v1), value = seq(0, 10, by = 5)) %>%
arrange(value, id)
# # A tibble: 12 x 3
# id v1 value
# <fct> <dbl> <dbl>
# 1 a 0.3 0
# 2 b 0.1 0
# 3 c 0.7 0
# 4 d 1.3 0
# 5 a 0.3 5
# 6 b 0.1 5
# 7 c 0.7 5
# 8 d 1.3 5
# 9 a 0.3 10
# 10 b 0.1 10
# 11 c 0.7 10
# 12 d 1.3 10
答案 3 :(得分:1)
使用lapply
(一种非常强大的工具)的解决方案:
dd <- data.frame(id = letters[1:4], v1 = c(0.3,0.1,0.7,1.3))
newdf<- lapply(c(0,5,10), function(value) {
cbind(dd, data.frame(value=rep(value,NROW(dd))))
})
newdf <- do.call('rbind',newdf)
# id v1 value
#1 a 0.3 0
#2 b 0.1 0
#3 c 0.7 0
#4 d 1.3 0
#5 a 0.3 5
#6 b 0.1 5
#7 c 0.7 5
#8 d 1.3 5
#9 a 0.3 10
#10 b 0.1 10
#11 c 0.7 10
#12 d 1.3 10
答案 4 :(得分:1)
使用splitstackshape
套餐参加聚会,
library(splitstackshape)
transform(expandRows(dd, count = 3, count.is.col = FALSE), value = c(0, 5, 10))
# id v1 value
#1 a 0.3 0
#1.1 a 0.3 5
#1.2 a 0.3 10
#2 b 0.1 0
#2.1 b 0.1 5
#2.2 b 0.1 10
#3 c 0.7 0
#3.1 c 0.7 5
#3.2 c 0.7 10
#4 d 1.3 0
#4.1 d 1.3 5
#4.2 d 1.3 10
答案 5 :(得分:1)
使用data.table
:
setDT(dd)[, .(value = c(0, 5, 10)), by = .(id, v1)]
输出:
id v1 value
1: a 0.3 0
2: a 0.3 5
3: a 0.3 10
4: b 0.1 0
5: b 0.1 5
6: b 0.1 10
7: c 0.7 0
8: c 0.7 5
9: c 0.7 10
10: d 1.3 0
11: d 1.3 5
12: d 1.3 10
如果您加载了magrittr
(或者如果您已经加载了dplyr
或tidyverse
),则可以继续使用管道setDT(dd)[, .(value = c(0, 5, 10)), by = .(id, v1)] %>% ...