问题描述
我有一个地址向量(下面显示了一个小片段)
df=c("westmoorings east","chaguanas proper","bloody bay","westmooorings","el doraldo","rousillac34") (full length=5432)
和参考城市/地区的另一个向量(请参见下面的代码段)
areas=c("arima","port of spain","chaguanas") (full length=20)
我想通过df
向量中的区域将areas
中的地址分组,例如,地址chaguanas proper
将被分组在chaguanas
下。我正在使用列表来存储结果。我用来实现此目的的代码是:
L=list()
for(i in 1:length(areas)){
ind=grep(paste(areas[i]),df)
L[i]=df[ind]
df[-ind] #updates the df to exclude all addresses already stored in L[i]
}
问题出在 L[i]=df[ind]
行中。我收到错误消息“ number of items to replace is not a multiple of replacement length
”,有人可以帮忙吗?我正在使用模式匹配,但是将结果存储在列表组件中会引发该错误。顺便说一下,我正在使用R。
解决方法
在您对代码进行一些细微更改后,我建议这样做:
import org.springframework.beans.BeanUtils;
BeanUtils.copyProperties(source,target);
输出:
#Data
df=c("westmoorings east","chaguanas proper","bloody bay","westmooorings","el doraldo","rousillac34")
areas=c("arima","port of spain","chaguanas")
#Code
L=list()
for(i in 1:length(areas)){
ind=which(grepl(paste(areas[i]),df))
if(length(ind)!=0)
{
L[i]=df[ind]
df[-ind]
}
}
,
我们可以用length
的'areas'预先初始化'L'并使用if
的条件,如注释中
L <- vector("list",length(areas))
for(i in seq_along(areas)){
ind <- grep(areas[i],df )
if(length(ind) > 0) {
L[[i]] <- df[ind]
df <- df[-ind]
}
}
L
#[[1]]
#NULL
#[[2]]
#NULL
#[[3]]
#[1] "chaguanas proper"
注意:这回答了OP发布的问题
如果我们要执行这种矢量化方式,则一个更简单的选择是(无循环,grep
仅被调用一次)
grep(paste(areas,collapse="|"),df,value = TRUE)
#[1] "chaguanas proper"
数据
df <- c("westmoorings east","rousillac34")
areas <- c("arima","chaguanas")
,
我认为在这里使用sapply
会更容易:
L <- sapply(areas,function(x) grep(x,value = TRUE))
L
#$arima
#character(0)
#$`port of spain`
#character(0)
#$chaguanas
#[1] "chaguanas proper"
使用tidyverse
函数的结果是:
purrr::map(areas,~stringr::str_subset(df,.x))
,
当您看到索引语法稍有错误时,通常会遇到R错误。在这种情况下,您似乎想遍历区域矢量的元素,但是在原始代码中,您要求R将返回值放置在列表“ L”的(上)“索引”级别中,即L[i]
。实际上,您应该将返回值放在列表“ L”的(较低)“值”级别中,即L[[i]]
。查看示例:
> Output_listA <- list()
> for(i in 1:length(areas)){
Output_listA[[i]] <- grep(areas[i],value=TRUE)
}
> Output_listA
[[1]]
character(0)
[[2]]
character(0)
[[3]]
[1] "chaguanas proper"
在Output_listA中,可以看到带有参数“ value = TRUE”的grep()
的使用。这将返回一个匹配列表。但是,也许您只是想对索引进行进一步的操作?然后使用grepl()
如下:
> Output_listB <- list()
> for(i in 1:length(areas)){
Output_listB[[i]] <- grepl(areas[i],df)
}
> Output_listB
[[1]]
[1] FALSE FALSE FALSE FALSE FALSE FALSE
[[2]]
[1] FALSE FALSE FALSE FALSE FALSE FALSE
[[3]]
[1] FALSE TRUE FALSE FALSE FALSE FALSE
> df[ Output_listB[[3]] ]
[1] "chaguanas proper"
最后,您可以让lapply()
函数为您完成工作。下面显示了grep()
的使用,但您也可以轻松使用grepl()
:
> lapply(areas,FUN = function(x) grep(x,value=TRUE) )
[[1]]
character(0)
[[2]]
character(0)
[[3]]
[1] "chaguanas proper"