我有一个数据框“cities.df”,它在一列中包含巴西的所有城市,在另一列中包含各自的州。
在其他数据框“tweets.df”中,我有一个包含推文的专栏,可能包含一些关于城市或州的参考。
我正在尝试做的是在tweets.df中添加一个列,并对其位置进行“估计”,假设如果他在圣保罗州的某个城市发布了某些内容,那么他就位于该州圣保罗。
我是R的新手,我能想到如何实现这一点的唯一方法是在所有推文上使用级联循环,然后在所有应用grep函数的城市进行循环。但这似乎不是用R实现它的正确方法。
for tweet in tweets
for city in cities
grep(city, tweet)
我想知道是否有更多“可矢量化”的方式来实现它。
由于
答案 0 :(得分:1)
您似乎希望根据推文中提到的城市,在识别州的推文上添加一列。这有几个问题。首先,城市并不是唯一的 - 也就是说,在不同的州可以有不止一个同名的城市。所以这个城市没有唯一的国家标识。其次,可以通过多种方式识别城市。例如,巴西有四种不同的圣保罗,它们都可能以同样的方式被引用,特别是在推文中。
São Paulo de Olivença
São Paulo do Potengi
São Paulo das Missões
São Paulo
尽管有这些保留意见,但这是一种附加城市和州名的方法。此代码还处理了推文中提及 no 城市的可能性。
library(raster)
# this generates sample data - you have this already (??)
br <- getData(country="BR",level=2) # Brazil shapefile, admin level 2
# muni$NAME_1 has the state names; muni$NAME_2 has the city names
muni <- br@data # ~5500 municipalities in Brazil
set.seed(1) # for reproduceable example
cities <- muni[sample(1:nrow(muni),90),]$NAME_2 # 90 random cities in brazil
cities <- c(cities,rep("",10)) # last 10% have no city mentioned
tweets <- sapply(1:100,function(i) paste("#random text",cities[i],"more random text"))
# you start here
result <- do.call(rbind,lapply(tweets,function(tweet) {
indx <- sapply(muni$NAME_2, grepl, tweet,fixed=T) # all matching cities
indx <- min(which(indx)) # use only first match!!
muni[indx,c("NAME_2","NAME_1")] # NAME_1 contains the state
}))
tweets <- data.frame(tweets,result)
head(tweets)
# tweets NAME_2 NAME_1
# 1462 #random text Piau more random text Piau Minas Gerais
# 2048 #random text Estiva more random text Estiva Minas Gerais
# 1474 #random text Nova Esperança do Sudoeste more random text Esperança Paraíba
# 4997 #random text Monções more random text Monções São Paulo
# 1110 #random text Goiás more random text Goiás Goiás
# 4941 #random text Jumirim more random text Jumirim São Paulo
tail(tweets)
# tweets NAME_2 NAME_1
# NA4 #random text more random text <NA> <NA>
# NA5 #random text more random text <NA> <NA>
# NA6 #random text more random text <NA> <NA>
# NA7 #random text more random text <NA> <NA>
# NA8 #random text more random text <NA> <NA>
# NA9 #random text more random text <NA> <NA>
此输出说明了另一个问题:Esperança
匹配,即使提到的实际城市是Nova Esperança do Sudoeste
(处于不同的状态......)。我没有看到一个简单的方法。
答案 1 :(得分:0)
这是你可以做到的一种方式。将cities
和tweets
视为从各自数据帧中提取的向量。这些推文显然是构成的,甚至不是单词。我只是通过抽样信件并将它们粘贴在一起来创建它们。如果添加一些数据,则要更新。
最后一行将返回包含cities
列表中的城市的推文。
> cities
# [1] "Belém" "Belo Horizonte" "Blumenau"
# [4] "Brasília" "Campinas" "Curitiba"
# [7] "Florianópolis" "Fortaleza" "Goiania"
# [10] "Macáe" "Manaus" "Niteroi"
# [13] "Porto Alegre" "Recife" "Rio de Janeiro"
# [16] "Roraima" "Salvador" "Santo Andre"
# [19] "Santos" "São José dos Campos" "São Paulo"
# [22] "Vitória"
> tweets
# [1] "Niteroi rjzzfbymh wj fa elxbmyfk logeb"
# [2] "no city present in this sentence"
# [3] "Vitória zl qxllds buoo fvclizxv zqf"
# [4] "Rio de Janeiro n zaocj u ouo bck"
# [5] "no city present in this sentence"
> unlist(sapply(seq(cities), function(i){
grep(cities[i], tweets, value = TRUE)
}))
# [1] "Niteroi rjzzfbymh wj fa elxbmyfk logeb"
# [2] "Rio de Janeiro n zaocj u ouo bck"
# [3] "Vitória zl qxllds buoo fvclizxv zqf"
答案 2 :(得分:-1)
好吧,你不需要迭代两者。 grep一次只能采用一种模式,但可以在向量中搜索结果就好了。所以
for city in cities
grep(city, tweets)
有点合理。