如何根据另一个变量的行上的值添加一定数量的行
Posted
技术标签:
【中文标题】如何根据另一个变量的行上的值添加一定数量的行【英文标题】:How to add certain number of rows based on values on the rows of another variable 【发布时间】:2018-08-02 21:36:51 【问题描述】:date time td number
20150102 80000 -1 0
20150102 80001 -1 2
20150102 80002 1 0
20150102 80003 1 3
20150102 80004 -1 0
我需要根据变量“数字”创建附加行数。并让日期和时间与编号的行相同,而变量 td=0。我想要这样的数据:
date time td number
20150102 80000 -1 0
20150102 80001 -1 2
20150102 80002 1 0
20150102 80003 1 3
20150102 80004 -1 0
20150102 80001 0 NA
20150102 80001 0 NA
20150102 80003 0 NA
20150102 80003 0 NA
20150102 80003 0 NA
【问题讨论】:
我需要通过这个循环运行,因为我有超过 20,000 个 obs 我不明白你的预期结果。你能澄清一下规则吗?为什么time
前 5 行会发生变化?为什么是新行中的值?
对不起!我原来的时间应该加1,请看我编辑的版本
【参考方案1】:
我会生成每一列,然后将它们绑定到一个数据框,然后将它们绑定到原始数据框!无需循环。
假设你的数据框叫做 df
#Create the date and time using the number column directly.
date <- rep(df$date, times = df$number)
time <- rep(df$time, times = df$number)
#Combine these fields into a data frame and set td to all 0s and number to all NAs
appenddf <- data.frame(date = date, time = time, td = 0, number = NA)
#Bind the data for appending to the original data frame
df <- rbind(df, appenddf)
【讨论】:
好答案!我在想同一条线,但你很快。 +1 谢谢!我怀疑可能有一个更强大的答案,它不依赖于创建单独的数据框,但我不知道它是不是在我的脑海中:)【参考方案2】:使用expandRows
和separate
函数可以实现另一个选项。展开行将允许使用组合值复制 rows
,稍后可以将其分离出来并添加到原始 df
。
library(splitstackshape)
library(dplyr)
df1 <- setDT(expandRows(df, "number"))[, newsamp :=
sprintf("%d-%d-%d-%d", date, time, 0, NA)][,newsamp] %>% as.data.frame() %>%
separate(1,c("date", "time", "td", "number"))
rbind(df, df1)
#Result
# date time td number
#1 20150102 80000 -1 0
#2 20150102 80001 -1 2
#3 20150102 80002 1 0
#4 20150102 80003 1 3
#5 20150102 80004 -1 0
#6 20150102 80001 0 NA
#7 20150102 80001 0 NA
#8 20150102 80003 0 NA
#9 20150102 80003 0 NA
#10 20150102 80003 0 NA
【讨论】:
【参考方案3】:这个循环将使用 rbind.fill(来自 plyr),用于数据帧 df
:
for (i in length(df$n))
x = df$n[i]
while (x > 0)
df <- rbind.fill(df, df[i,1:2])
x = x -1
print(x)
#Switch NA's in df$td column to 0
df$td[is.na(df$td)] <- 0
【讨论】:
【参考方案4】:> a=rep(1:nrow(dat),dat$number+1)
> transform(dat[c(a[!duplicated(a)],a[duplicated(a)]),-4],num=`length<-`(dat$number,length(a)))
date time td num
1 20150102 80000 -1 0
2 20150102 80001 -1 2
3 20150102 80002 1 0
4 20150102 80003 1 3
5 20150102 80004 -1 0
2.1 20150102 80001 -1 NA
2.2 20150102 80001 -1 NA
4.1 20150102 80003 1 NA
4.2 20150102 80003 1 NA
4.3 20150102 80003 1 NA
【讨论】:
以上是关于如何根据另一个变量的行上的值添加一定数量的行的主要内容,如果未能解决你的问题,请参考以下文章