我有什么:
test_df <- data.frame(isolate=c(1,2,3,4,1,2,3,4,5),label=c(1,1,1,1,2,2,2,2,2),alignment=c("--at","at--","--at","--at","a--","acg","a--","a--", "agg"))
> test_df
isolate label alignment
1 1 1 --at
2 2 1 at--
3 3 1 --at
4 4 1 --at
5 1 2 a--
6 2 2 acg
7 3 2 a--
8 4 2 a--
9 5 2 agg
我想要什么:
我想将对齐字段分成两列,位置和字符:
> test_df
isolate label aln_pos aln_char
1 1 1 1 -
2 1 1 2 -
3 1 1 3 a
4 1 1 4 t
...
并非所有路线都具有相同的长度,但所有具有相同标签的路线都具有相同的长度。
我尝试了什么:
我原以为我可以使用separate
首先让每个位置都有自己的列,然后使用gather
将这些列转换为键值对。但是,我还没能把单独的部分弄好。
答案 0 :(得分:1)
在基础R中,您可以使用索引以及strsplit
这样的列表创建。
# make variable a character vector
test_df$alignment <- as.character(test_df$alignment)
# get list of individual characters
myList <- strsplit(test_df$alignment, split="")
然后构建data.frame
# construct data.frame
final_df <- cbind(test_df[rep(seq_len(nrow(test_df)), lengths(myList)),
c("isolate", "label")],
aln_pos=sequence(lengths(myList)),
aln_char=unlist(myList))
在这里,我们采用原始data.frame的前两列,并使用rep
在第二个参数中使用向量输入重复行,告诉它在第一个参数中重复相应值的次数。使用lengths
计算次数。 cbind
的第二个参数是调用sequence
获取相同的lengths
输出。这会产生从1到相应长度的计数。第三个参数是未列出的字符值。
返回
head(final_df, 10)
isolate label aln_pos aln_char
1 1 1 1 -
1.1 1 1 2 -
1.2 1 1 3 a
1.3 1 1 4 t
2 2 1 1 a
2.1 2 1 2 t
2.2 2 1 3 -
2.3 2 1 4 -
3 3 1 1 -
3.1 3 1 2 -
答案 1 :(得分:1)
由于您提到tidyr::gather
,您可以尝试这样做:
test_df <- data.frame(isolate=c(1,2,3,4,1,2,3,4,5),
label=c(1,1,1,1,2,2,2,2,2),
alignment=c("--at","at--","--at","--at","a--","acg","a--","a--", "agg"),
stringsAsFactors = FALSE)
library(tidyverse)
test_df %>%
mutate(alignment = strsplit(alignment,"")) %>%
unnest(alignment)