我有一个像
这样的数据框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循环获取此数据框,但这将是乏味的。是否有任何简洁明了的方法来实现这一目标?
提前致谢。
答案 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