使用公共元素连接两个字符串

问题描述 投票:0回答:2

我正在研究R中的一个简单问题(但我还没想到它; p):

给出一个矢量vect1 <- c("Andy+Pete", "Mary + Pete", "Pete+ Amada", ..., "Amada + Steven", "Steven + Henry")。我想创建一个新的矢量vect2,它包含vect1中的所有元素和共享以下属性的新元素:对于每两个字符串"A+B""B+C",我们将它连接到"A+C"并将这个新元素添加到vect2中。有人可以帮我这么做吗?

另外,我想让每个字符串中的所有元素都站在+前面,以下代码是否正确?

for (i in length(vect1)){ vect3[i] <- regexpr(".*+", vect1[i]) }

第三个问题:如果我有d格式的Date格式的数据框%d-%b(例如,01-Apr),我该如何根据Date以递增顺序排序这个数据框?我们只想说d <- c(01-Apr,01-Mar,02-Jan,31-June,30-May)

r string concat
2个回答
1
投票

我认为你可以(应该)避免使用for循环和使用外部lib(如果不需要)。

所以这可能是一个解决方案:

// create data
vect1 <- c("Andy+Pete", "Mary + Pete", "Pete+ Amada", "Amada + Steven", "Steven + Henry")

// create a matrix of pairs with removed white spaces
pairsMatrix <- do.call(rbind, sapply(vect1, function(v) strsplit(gsub(pattern = " ", replacement = "", x = v), "\\+")))

// remove dimnames (not necessary though)
dimnames(pairsMatrix) <- NULL

// for all line of the pairsMatrix, find if second element is somewhere else first element. Bind that with the previous pairs
allPairs <- do.call(rbind, c(list(pairsMatrix), apply(pairsMatrix, 1, function(names) c(names[1], pairsMatrix[names[2]==pairsMatrix[,1], 2]))))

// filter for oneself-relationships
allPairs[allPairs[,1]!=allPairs[,2],]

      [,1]     [,2]    
 [1,] "Andy"   "Pete"  
 [2,] "Mary"   "Pete"  
 [3,] "Pete"   "Amada" 
 [4,] "Amada"  "Steven"
 [5,] "Steven" "Henry" 
 [6,] "Andy"   "Amada" 
 [7,] "Mary"   "Amada" 
 [8,] "Pete"   "Steven"
 [9,] "Amada"  "Henry" 

关于你的最后一点,我认为使用适当的Date对象进行简单的排序就可以了。


1
投票

我认为应该这样做,但我做了我可能不应该做的事情......比如生长对象和嵌套for循环。如果你想访问'+'前面的所有元素,只需使用name.matrix[,1]

vect1 <- c("Andy+Pete", "Mary + Pete", "Pete+ Amada","Amada + Steven", "Steven + Henry")

library(stringr)

name.matrix <- matrix(do.call('rbind',str_split(vect1, pattern = "\\s?[+]\\s?")), ncol = 2)

new.stuff <- c()

for(x in unique(name.matrix[,2])){
  sub.mat.1 <- matrix(name.matrix[name.matrix[,2] == x,], ncol = 2)
  sub.mat.2 <- matrix(name.matrix[name.matrix[,1] == x,], ncol = 2)
  if(length(sub.mat.1) && length(sub.mat.2)){
    for(y in seq_along(sub.mat.1[,2])){
      new.add <- paste0(sub.mat.1[y,1],'+', sub.mat.2[,2])
      new.stuff <- c(new.stuff, new.add)
    }
  }
}

vect2 <- c(vect1, new.stuff)
vect2
#[1] "Andy+Pete"      "Mary + Pete"    "Pete+ Amada"    "Amada + Steven" "Steven + Henry" "Andy+Amada"    
#[7] "Mary+Amada"     "Pete+Steven"    "Amada+Henry" 

更新:

第三个问题。那么六月只有30天。所以你会在那里得到一个NA。如果它是您尝试根据日期排序的data.frame,则需要使用格式df[order(df$Date),]。使用日期时,lubridate包也可能会有所帮助。

d <- c('01-Apr','01-Mar','02-Jan','31-June','30-May')

d.new <- as.Date(d, format = '%d-%b')
d.new <- d.new[order(d.new)]
d.new
#[1] "2018-01-02" "2018-03-01" "2018-04-01" "2018-05-30" NA  
© www.soinside.com 2019 - 2024. All rights reserved.