我正在尝试创建查看两个CSV文件的代码:一个是所有鸟类及其活动范围的世界列表,另一个是喜马拉雅山上所有鸟类的文件。我需要检查CSV文件中的每个物种与国际奥委会世界列表一上的匹配物种,看看这只鸟是否真的在范围内(这意味着在Range列中会显示"India"或"himalayas"或"s e Asia" )。我想创建一个函数,可以输入两个数据集,查找名称匹配的位置,检查range是否包含这些单词,并返回不包含这些单词的位置,这样我就可以专门检查这些鸟了。下面是我目前所拥有的(我使用的是RStudio):
myfunc <- function() {
if ((bird_data$Scientific.name == ioc$Scientific.name) & (ioc$Scientific.name!=("Himalayas" | "se Asia" | "India")) {
print(eval(bird_data$Common.Name[bird_data$Scientific.name == ioc$Scientific.name) & (ioc$Scientific.name!=("Himalayas" | "se Asia" | "India")]))
}
}
save("myfunc", file = "myfunc.Rdata")
source("myfunc.Rdata")我想我搞砸了,因为没有输入。所以我尝试了一种新的方法:
compare = function(data1, data2) {
....
}但对于上面的内容,我不知道如何让函数识别适当的数据子集(比如我不能说data1$Scientific.name)。
发布于 2016-04-15 17:31:39
如果没有一个最小的可重现的例子,就很难回答这个问题-如果没有任何关于你正在比较的两个数据帧的知识,就很难制定出解决方案-请参阅上面alistaire评论中的链接,了解如何提供解决方案。
我建议你更改你的问题标题,使它更具信息性-“在R中创建函数”表明你想知道R中的函数所需的语法-我建议“用Grep对数据帧进行子集,然后在R中过滤结果”--这就是我认为你实际上正在尝试做的事情。
假设你从国际鸟类学委员会website获得了国际奥委会世界名录数据,我不确定你在函数中描述的方法是否可以作为育种范围-亚区列中的数据,例如:
w Himalayas to s Siberia and w Mongolia
Himalayas to c China
e Afghanistan to nw India and w Nepal
e Afghanistan to w Tibetan plateau and n India
Africa south of the Sahara, s and se Asia这些值都不同于“印度”、“喜马拉雅”或“东南亚”,并且您的函数将不会返回任何一个精确匹配的值。您需要使用grep来查找数据中存在的子字符串。
让我们创建一个玩具数据集。
bird_data <- data.frame(
Scientific.name=c(
"Chicken Little",
"Woodstock",
"Woody Woodpecker",
"Donald Duck",
"Daffy Duck",
"Big Bird",
"Tweety Pie",
"Foghorn Leghorn",
"The Road Runner",
"Angry Birds"))
ioc_data <- data.frame(
Scientific.name=c(
"Chicken Little",
"Woodstock",
"Woody Woodpecker",
"Donald Duck",
"Daffy Duck",
"Big Bird",
"Tweety Pie",
"The Road Runner",
"Angry Birds"),
subrange=c(
"Australia, New Zealand",
"w Himalayas to s Siberia and w Mongolia",
"Himalayas to c China",
"e Afghanistan to nw India and w Nepal",
"e Afghanistan to w Tibetan plateau and n India",
"Africa south of the Sahara, s and se Asia",
"Amazonia to n Argentina",
"n Eurasia",
"n North America"))我会把你正在尝试做的事情分成两个步骤。
步骤1
使用grep根据您的搜索词是否在subrange列中找到来设置ioc_data数据框子集:
searchTerms <- c("India", "himalayas", "SE Asia")
#Then we use grep to return the indexes of matching rows:
matchingIndexes <- grep(paste(searchTerms, collapse="|"),
ioc_data$subrange,
ignore.case=TRUE) #Important so search such as "SE Asia" will match "se asia"
#We can then use our matching indexes to subset our ioc_data dataframe producing
#a subset of data corresponding to our range of interest:
ioc_data_subset <- ioc_data[matchingIndexes,]步骤2
如果我正确理解了您的问题,您现在希望从bird_data中提取ioc_data_subset中不存在的行(即,bird_data中的哪些行是针对在国际奥委会数据中没有记录为栖息在“印度”、“东南亚”和“喜马拉雅”子范围内的鸟类的。
我会使用Hadley Wickham的dplyr包来解决这个问题--一个很好的小抄可以在here上找到。安装dplyr后
library(dplyr)
#Create a merged dataframe containing all the data in one place.
merged_data <- dplyr::left_join(bird_data,
ioc_data,
by = "Scientific.name")
#Use an anti_join to select any rows in merged_data that are NOT present in
#ioc_data_subset
results <- dplyr::anti_join(merged_data,
ioc_data_subset,
by = "Scientific.name")首先需要left_join,否则我们在最终数据库中就不会有subrange列。请注意,任何不在IOC_data中的bird_data中的物种都将在subrange列中返回NA,以指示未找到数据。
results
Scientific.name subrange
1 Angry Birds n North America
2 The Road Runner n Eurasia
3 Foghorn Leghorn <NA>
4 Tweety Pie Amazonia to n Argentina
5 Chicken Little Australia, New Zealandhttps://stackoverflow.com/questions/35966356
复制相似问题