我有一个数据框,其中的一列包含字符串及其分数。有没有一种方法来创建一个新的数据框,其中每个字符串中的特定字母的位置及其得分。这是一个示例数据框
df<- data.frame( string = do.call(paste0, replicate(10, sample(LETTERS, 5, TRUE), FALSE)),
start = round(runif(5,100,500),0),
score = round(runif(5,10,50),1)
head(df)
它看起来像这样:
String start score
TRIRXBGFPI 219 46.1
QBPWJOTFLQ 430 21.5
PWVEEHKTFW 399 37.2
AWGAFAHGQF 246 16.4
ZDLYRUTZBB 380 32.1
现在,我希望能够读取字符串的每个字母并记录每个“ B”的位置及其得分。所以预期的输出将是
string position start score
TRIRXBGFPI 6 219 46.1
QBPWJOTFLQ 2 430 21.5
ZDLYRUTZBB 9 380 32.1
ZDLYRUTZBB 10 380 32.1
我的方法是在字符串列上使用grepl过滤掉不带B的字符串,然后运行两个for循环以读取每个字符串的每个字母并记录其位置。有人可以建议一种更好的方法吗?
谢谢
答案 0 :(得分:2)
我们可以使用str_locate
library(tidyverse)
df %>%
mutate(position = str_locate_all(String, "B") %>%
map(~ .x[,1])) %>%
unnest
# String start score position
#1 TRIRXBGFPI 219 46.1 6
#2 QBPWJOTFLQ 430 21.5 2
#3 ZDLYRUTZBB 380 32.1 9
#4 ZDLYRUTZBB 380 32.1 10
或使用gregexpr
中的base R
lst <- lapply(gregexpr("B", df$String), function(x) as.numeric(x * NA^(x < 0)))
# or use strsplit to split the string and then get the index with which
#lst <- lapply(strsplit(df$String, ""), function(x) {
# x1 <- which(x == "B")
# if(length(x1) == 0) NA else x1})
out <- df[rep(seq_len(nrow(df)), lengths(lst)),]
out$position <- unlist(lst)
out1 <- out[!is.na(out$position),]
row.names(out1) <- NULL
out1
# String start score position
#1 TRIRXBGFPI 219 46.1 6
#2 QBPWJOTFLQ 430 21.5 2
#3 ZDLYRUTZBB 380 32.1 9
#4 ZDLYRUTZBB 380 32.1 10
df <- structure(list(String = c("TRIRXBGFPI", "QBPWJOTFLQ", "PWVEEHKTFW",
"AWGAFAHGQF", "ZDLYRUTZBB"), start = c(219L, 430L, 399L, 246L,
380L), score = c(46.1, 21.5, 37.2, 16.4, 32.1)), class = "data.frame",
row.names = c(NA, -5L))
答案 1 :(得分:2)
另一个tidyverse选项,使用gregexpr
......
library(tidyverse)
df %>%
mutate(position = gregexpr("B", String)) %>%
unnest(position) %>%
filter(position>0)
String start score position
1 TRIRXBGFPI 219 46.1 6
2 QBPWJOTFLQ 430 21.5 2
3 ZDLYRUTZBB 380 32.1 9
4 ZDLYRUTZBB 380 32.1 10
答案 2 :(得分:0)
以R
为基础:
df[["position"]] <-
sapply(gregexpr(pattern ='B', df[["String"]]), "[", 1)
subset(df, position > 0)
String start score position
1 TRIRXBGFPI 219 46.1 6
2 QBPWJOTFLQ 430 21.5 2
5 ZDLYRUTZBB 380 32.1 9
数据:
df <- data.frame(
String = c("TRIRXBGFPI", "QBPWJOTFLQ", "PWVEEHKTFW", "AWGAFAHGQF", "ZDLYRUTZBB"),
start = c(219L, 430L, 399L, 246L, 380L),
score = c(46.1, 21.5, 37.2, 16.4, 32.1)
)