我有数据框z1
:
z1 <- data.frame(time=as.factor(rep(0.5:9.5,times=rep(c(9,10,8,11,12),2))),
roi= rep(c(1:9,1:10,1:8,1:11,1:12),2), area=runif(100, 5.0, 7.5))
我想要创建一个新的数据框z2
,其中10*nrow(z1)
行包含条件:
在每个time
值处,(z1$roi[i:i+1] and z1$area[i:i+1])
的每第二行i in 1: c(nrow(z1) -1)
用于在roi
中生成列area
和z2
,例如
z2$roi <- seq(z1$roi[i],z1$roi[i+1], length.out = 10)
z2$area <- seq(z1$area[i],z1$area[i+1], length.out = 10)
如果数据框z1
如下:
time roi area
1 0.5 1 6.181150 #=z1$roi[1]
2 0.5 2 5.469366 #=z1$roi[2]
3 0.5 3 6.742525
.
.
.
98 9.5 10 6.063234
99 9.5 11 6.824393 #=z1$roi[99]
100 9.5 12 7.346298 #=z1$roi[100]
数据框z2
将是:
time roi area
1 0.5 1.000000 6.181150 #=z1$roi[1]
2 0.5 1.111111 6.102063
.
.
.
9 0.5 1.888889 5.548453
10 0.5 2.000000 5.469366 #=z1$roi[2]
.
.
.
991 9.5 11.00000 6.824393 #=z1$roi[99]
992 9.5 11.11111 6.882383
.
.
.
999 9.5 11.88889 7.288309
1000 9.5 12.00000 7.346298 #=z1$roi[100]
任何人都可以帮助我吗?谢谢!
答案 0 :(得分:2)
使用tidyverse
,更改您的值以欣赏输出(将5
替换为10
):
z1 <- head(z1,3)
library(tidyverse)
z1 %>%
mutate_at(vars(roi,area),~map2(.,c(.[-1],last(.)),~seq(.x,.y,length.out=5))) %>%
unnest %>%
head(-5)
# time roi area
# 1 0.5 1.00 6.302351
# 2 0.5 1.25 6.151644
# 3 0.5 1.50 6.000938
# 4 0.5 1.75 5.850231
# 5 0.5 2.00 5.699525
# 6 0.5 2.00 5.699525
# 7 0.5 2.25 5.687045
# 8 0.5 2.50 5.674566
# 9 0.5 2.75 5.662087
# 10 0.5 3.00 5.649608
我们会对cols time
和area
应用相同的转换,因此我们对这些转换使用mutate_at
。
我们希望将它们转换为包含向量的列表列,因此我们可以unnest
之后获得很长的data.frame
(您可能需要了解tidyr::unnest
才能理解这一步,基本上它会使data.frame
data.frame
,vectors
或嵌套lists
成为data.frames
中的常规&{39} purrr::map2
作为要素)。
地图系列将返回此类列表输出,但每个值都取决于当前的AND下一个值,因此我们使用.
来获取两个输入。
c(.[-1],last(.))
是当前值,data.frames
是下一个值(对于最后一个元素,没有下一个值,所以我们保留最后一个值)。
我们不需要创建一个长head(-n)
。
重复的最后一个值创建了重复的行,因此我们使用 else:
r.write('1')
x = int(r.read())
y = 1000000
while x<y:
time.sleep(2)
x=x+1
await client.say(x)
r.write(x)
if x==y:
await client.say('Reached one million')
quit()
答案 1 :(得分:2)
您可以使用approx()
:
s1 <- seq_len(nrow(z1)-1)
s2 <- rep(s1,each=9)
out <- approx(
x = seq_along(z1$area),
y = z1$area,
xout = c(s2 + head(seq(0,1,length.out=10),-1), nrow(z1))
)$y
z1
# time roi area
#1 0.5 1 6.413124
#2 0.5 2 6.837422
#3 0.5 3 6.656612
然后使用行索引将结果重新加入:
cbind(z1[c(s2,nrow(z1)),], out)
# time roi area out
#1 0.5 1 6.413124 6.413124
#1.1 0.5 1 6.413124 6.460268
#1.2 0.5 1 6.413124 6.507413
#1.3 0.5 1 6.413124 6.554557
#1.4 0.5 1 6.413124 6.601701
#1.5 0.5 1 6.413124 6.648845
#1.6 0.5 1 6.413124 6.695989
#1.7 0.5 1 6.413124 6.743134
#1.8 0.5 1 6.413124 6.790278
#2 0.5 2 6.837422 6.837422
#2.1 0.5 2 6.837422 6.817332
#2.2 0.5 2 6.837422 6.797242
#2.3 0.5 2 6.837422 6.777152
#2.4 0.5 2 6.837422 6.757062
#2.5 0.5 2 6.837422 6.736972
#2.6 0.5 2 6.837422 6.716882
#2.7 0.5 2 6.837422 6.696792
#2.8 0.5 2 6.837422 6.676702
#3 0.5 3 6.656612 6.656612
这种逻辑应该比必须为每行计算序列更好地缩放多。从快速而肮脏的测试开始,对于100万行,大约需要10秒,而1分钟。