我有一个data.frame,有一个列,一个字符串向量。
这些字符串具有重复值。 我想找到在这个向量中有重复的字符串,并在新列中写下它们的位置索引。
例如,考虑一下:
DT<- data.frame(string=A,B,C,D,E,F,A,C,F,Z,A)
我想得到:
string match2 match2 match3 matchx....
A 1 7 11
B 2 NA NA
C 3 8 NA
D 4 NA NA
E 5 NA NA
F 6 9 NA
A 1 7 11
C 3 8 NA
F 6 9 NA
Z 10 NA NA
A 1 7 11
字符串的长度比本例中的长,我不知道我需要的最大列数。
最有效的方法是什么? 我知道有重复的功能,但我不确定如何将它与我想要的结果相结合。
非常感谢!
答案 0 :(得分:3)
这是实现这一目标的一种方式。我确定有一个data.table one liner。
DT<- data.frame(string=c("A","B","C","D","E","F","A","C","F","Z","A"))
# find matches
rbf <- sapply(DT$string, FUN = function(x, DT) which(DT %in% x), DT = DT$string)
# fill in NAs to have a pretty matrix
out <- sapply(rbf, FUN = function(x, mx) c(x, rep(NA, length.out = mx - length(x))), max(sapply(rbf, length)))
# bind it to the original data
cbind(DT, t(out))
string 1 2 3
1 A 1 7 11
2 B 2 NA NA
3 C 3 8 NA
4 D 4 NA NA
5 E 5 NA NA
6 F 6 9 NA
7 A 1 7 11
8 C 3 8 NA
9 F 6 9 NA
10 Z 10 NA NA
11 A 1 7 11
答案 1 :(得分:2)
以下是data.table
的一个选项。按&#39;字符串&#39;分组后,获取序列(seq_len(.N)
)和行索引(.I
),然后dcast
到&#39;宽&#39;格式化并加入原始数据集on
&#39;字符串&#39;
library(data.table)
dcast(setDT(DT)[, .(seq_len(.N),.I), string],string ~ paste0("match", V1))[DT, on = "string"]
# string match1 match2 match3
# 1: A 1 7 11
# 2: B 2 NA NA
# 3: C 3 8 NA
# 4: D 4 NA NA
# 5: E 5 NA NA
# 6: F 6 9 NA
# 7: A 1 7 11
# 8: C 3 8 NA
# 9: F 6 9 NA
#10: Z 10 NA NA
#11: A 1 7 11
或者另一种选择是split
带有&#39;字符串&#39;的行序列,填充list
元素NA
的长度更短,{ {1}}使用原始数据集(使用merge
方法)
base R
lst <- split(seq_len(nrow(DT)), DT$string)
merge(DT, do.call(rbind, lapply(lst, `length<-`, max(lengths(lst)))),
by.x = "string", by.y = "row.names")
答案 2 :(得分:1)
这是一个使用tidyverse
工具(不是一个单行;)的人:)
library( tidyverse )
DT %>% group_by( string ) %>%
do( idx = which(DT$string == unique(.$string)) ) %>%
ungroup %>% unnest %>% group_by( string ) %>%
mutate( m = stringr::str_c( "match", 1:n() ) ) %>%
spread( m, idx )