将列中的值从c(a,b)拆分为R数据帧中的a和b

时间:2014-10-15 20:47:02

标签: r position substring

我想在子字符串中找到文本的不同位置。假设我有如下数据框:

Key String
10  09123022130908123
11  01230012780981093
12  12387109387126309

不知道如何将这个放在表格中,但这个想法是每个键都有一长串数字。要找到文字的位置' 09'在每个字符串中,我使用了代码:

df$try<-gregexpr(pattern ='09',df$string)

这给了我表格

Key String            try
10  09123022130908123 c(1,11)
11  01230012780981093 c(11,15)
12  12387109387126309 c(7,16)

现在我想要在不同列中使用纯数字而不是包含c(a,b)的单个列。如何将这些值拆分为不同列中的a和b? 欢迎任何其他建议在子字符串中获取所需文本的所有位置。 感谢

2 个答案:

答案 0 :(得分:2)

您仍然可以使用gregexpr。但是,您需要循环浏览gregexpr个结果,并使匹配的长度相同,并使用NA填充空值。使用df(在下面发布),您可以

g <- gregexpr("09", df$string, fixed = TRUE)
cbind(df, t(sapply(g, `length<-`, max(sapply(g, length)))))
#   key            string  1  2
# 1  10 09123022130908123  1 11
# 2  11 01230012780981093 11 15
# 3  12 12387109387126309  7 16
# 4  13 88888888888888809 16 NA

如果您在多种模式下执行此操作,这里有一个可能有帮助的小功能

where <- function(data, col, pattern, ...) 
{
    g <- gregexpr(pattern, data[[col]], ...)
    dc <- do.call(rbind, lapply(g, function(x) {
        x <- if(any(x < 0)) NA else x
        `length<-`(x, max(sapply(g, length)))
    }))
    colnames(dc) <- letters[1:ncol(dc)]
    cbind(df, dc)
}

一些示例运行:

where(df, "string", "8", fixed = TRUE)
#   key            string  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o
# 1  10 09123022130908123 14 NA NA NA NA NA NA NA NA NA NA NA NA NA NA
# 2  11 01230012780981093 10 13 NA NA NA NA NA NA NA NA NA NA NA NA NA
# 3  12 12387109387126309  4 10 NA NA NA NA NA NA NA NA NA NA NA NA NA
# 4  13 88888888888888809  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
where(df, "string", "09", fixed = TRUE)
#   key            string  a  b
# 1  10 09123022130908123  1 11
# 2  11 01230012780981093 11 15
# 3  12 12387109387126309  7 16
# 4  13 88888888888888809 16 NA
where(df, "string", "12", fixed = TRUE)
#   key            string  a  b
# 1  10 09123022130908123  3 15
# 2  11 01230012780981093  2  7
# 3  12 12387109387126309  1 12
# 4  13 88888888888888809 NA NA

数据:

df <- 
structure(list(key = c(10, 11, 12, 13), string = structure(c(2L, 
1L, 3L, 4L), .Label = c("01230012780981093", "09123022130908123", 
"12387109387126309", "88888888888888809"), class = "factor")), .Names = c("key", 
"string"), row.names = c(NA, -4L), class = "data.frame")

答案 1 :(得分:1)

也许不是超级漂亮而是工作。首先是你的数据:

df <- data.frame(
  key = c(10,11,12,13),
  string = c( 
    "09123022130908123",
    "01230012780981093",
    "12387109387126309",
    "88888888888888809" 
  )
)

我在这里使用lapplyfunctionwhichmatch为您提供第一,第二等匹配

searchString <- function( string, whichmatch) {
    x <- unlist(gregexpr(pattern ='09', string ))[whichmatch]
    return(x)
} 
df$a <- lapply( df$string, FUN = function(x) { searchString( x, 1 ) })
df$b <- lapply( df$string, FUN = function(x) { searchString( x, 2 ) })
rm(searchString)

  key            string  a  b
1  10 09123022130908123  1 11
2  11 01230012780981093 11 15
3  12 12387109387126309  7 16
4  13 88888888888888809 16 NA