如何重复具有特定模式的数据帧行?

时间:2014-10-16 20:13:46

标签: r dataframe

我有一个像

这样的数据框
col1    col2    col3    col4    col5
1        A       12      13      14
2        B       87      56      44
3        C       45      23      33
4        D       56      87      56

一个载体

 c("E", "F", "G")

我必须得到这样的东西:

col1    col2    col3    col4    col5
1        A       12      13      14
0        E       0       0       0
0        F       0       0       0
0        G       0       0       0
2        B       87      56      44
0        E       0       0       0
0        F       0       0       0
0        G       0       0       0
3        C       45      23      33
0        E       0       0       0
0        F       0       0       0
0        G       0       0       0
4        D       56      87      56
0        E       0       0       0
0        F       0       0       0
0        G       0       0       0

我可以使用for循环获取此数据框,但这将是乏味的。是否有任何简洁明了的方法来实现这一目标?

提前致谢。

4 个答案:

答案 0 :(得分:2)

这是一个使用行索引的可能(矢量化)解决方案。假设您的数据名为df,而您的数据名为V,则可以尝试

df2 <- df[rep(seq_len(nrow(df)), each = length(V) + 1), ]
df2[grep("[.]", row.names(df2)), ] <- 0
df2[grep("[.]", row.names(df2)), "col2"] <- V
# row.names(df2) <- seq_len(nrow(df2)) # Optional, if you don't like your row names
df2
#    col1 col2 col3 col4 col5
# 1     1    A   12   13   14
# 2     0    E    0    0    0
# 3     0    F    0    0    0
# 4     0    G    0    0    0
# 5     2    B   87   56   44
# 6     0    E    0    0    0
# 7     0    F    0    0    0
# 8     0    G    0    0    0
# 9     3    C   45   23   33
# 10    0    E    0    0    0
# 11    0    F    0    0    0
# 12    0    G    0    0    0
# 13    4    D   56   87   56
# 14    0    E    0    0    0
# 15    0    F    0    0    0
# 16    0    G    0    0    0

答案 1 :(得分:0)

添加新行很简单,但是按照您想要的方式对它们进行排序是很棘手的。如果最终订单不重要,您可以忽略sorting.vec

txt = "col1    col2    col3    col4    col5
1        A       12      13      14
2        B       87      56      44
3        C       45      23      33
4        D       56      87      56"

tmp <- read.table(text=txt, header=T, stringsAsFactors=F)
v2 <- c("E", "F", "G")

# add the mostly empty data
tmp2 <- data.frame(col1=0, col2=rep(v2, nrow(tmp)),
                   col3=0, col4=0, col5=0)

# encoding vector for sorting at the end (took some figuring out)
sorting.vec <- 1000* c(1:nrow(tmp), rep(1:nrow(tmp), each=length(v2))) +
               c(rep(0, nrow(tmp)), rep(1:length(v2), nrow(tmp)))

# stack and sort apropriately
final <- rbind(tmp, tmp2)[order(sorting.vec),]

答案 2 :(得分:0)

您可以尝试使用Map生成序列。

df <- data.frame(col1 = 1:4,
col2 = LETTERS[1:4],
col3 = c(12,87,45,56),
col4=c(13,56,23,87),
col5=c(14,44,33,56))

vec <- c("E","F","G")

df2 <- data.frame(col1 = 0, col2 = vec, col3=0, col4=0, col5=0)

#rbind
df3 <- rbind(df2, df)

#generate new sequence for rows
df4<-df3[unlist(Map(c, (nrow(df2)+1):nrow(df3), list(1:nrow(df2)))),]

答案 3 :(得分:0)

您可以创建所需表格的结构,然后只需分配原始数据框中的行。

df <- read.table(header=T, text='
                 col1    col2    col3    col4    col5
1        A       12      13      14
2        B       87      56      44
3        C       45      23      33
4        D       56      87      56')

v1 <- c(levels(df$col2))
v2 <- c(LETTERS[5:7])
new_df <- do.call("rbind", sapply(1:length(v1), FUN=function(x) expand.grid(0,c(v1[x],v2),0,0,0), simplify=F))

new_df[seq(from=1,to=nrow(new_df), by=4),] <- df
colnames(new_df) <- colnames(df)

   col1 col2 col3 col4 col5
1     1    A   12   13   14
2     0    E    0    0    0
3     0    F    0    0    0
4     0    G    0    0    0
5     2    B   87   56   44
6     0    E    0    0    0
7     0    F    0    0    0
8     0    G    0    0    0
9     3    C   45   23   33
10    0    E    0    0    0
11    0    F    0    0    0
12    0    G    0    0    0
13    4    D   56   87   56
14    0    E    0    0    0
15    0    F    0    0    0
16    0    G    0    0    0