R可以自动识别并计算n列中单词出现的次数吗?

时间:2015-07-06 03:23:22

标签: r

这是一个很重要的问题,但我会尽力解释。我正在尝试编写一个程序,跟踪昆虫随着时间的推移访问了一种花的次数。为此,我有一个看起来像这样的数据集:

ID          Visit_Freq   Visitor_1   Visitor_2   Visitor_3   Visitor_4   Visitor_5
1             1.0000000  Halictidae       <NA>       <NA>       <NA>       <NA>
2             5.0000000  Syrphidae Halictidae  Syrphidae  Syrphidae       Apis
3             1.0000000        Apis       <NA>       <NA>       <NA>       <NA>
4             0.0000000        <NA>       <NA>       <NA>       <NA>       <NA>
5             0.0000000        <NA>       <NA>       <NA>       <NA>       <NA>
6             0.0000000        <NA>       <NA>       <NA>       <NA>       <NA>
7             0.0000000        <NA>       <NA>       <NA>       <NA>       <NA>
8             2.0000000        Apis       Apis       <NA>       <NA>       <NA>
9             0.0000000        <NA>       <NA>       <NA>       <NA>       <NA>
10            0.0000000        <NA>       <NA>       <NA>       <NA>       <NA>

在“Visitor_n”栏目下,我记录了一种曾经访问该花的昆虫,或者没有访问过的NA。为了分析我们的数据,我们必须在每个访客列中计算每种昆虫类型。有时我们可以有多达10个访客花(ID),我们的ID数通常超过500,所以手工计算事件可能是一件苦差事。以下是我为简化工作所做的工作:

Apis <- sum(apply(DataSet[3:7], 2, function(x) length(which(x == 'Apis'))))

到目前为止,上面的这行已经很好地计算了Apis在我的真实数据集中出现的次数,但问题是有几十种昆虫类型可能会或可能不会访问我们的植物,所以到为了安全起见,我必须有大约30-50个类似的代码行,每个代码都用不同的昆虫类型代替“Apis”...例如......

Apis <- sum(apply(DataSet[3:7], 2, function(x) length(which(x == 'Apis'))))
Bombus <- sum(apply(DataSet[3:7], 2, function(x) length(which(x == 'Bombus'))))
Halictidae <- sum(apply(DataSet[3:7], 2, function(x) length(which(x == 'Halictidae'))))
Syrphidae <- sum(apply(DataSet[3:7], 2, function(x) length(which(x == 'Syrphidae'))))
Skipper <- sum(apply(DataSet[3:7], 2, function(x) length(which(x == 'Skipper'))))

等等。

如果我能找到一种方法让R自动识别“昆虫A,B,D,F和H出现在列[3:7]中,这将是非常有用的,这是他们的次数例如,所有这些都发生在一起,而不是必须输入每条昆虫的30-50行,以确保我没有遗漏任何东西。

我并不反对安装包来做这件事,但如果可能的话,我想尽可能保持它与基地R尽可能接近。我想向一些几乎没有R经验的实验室伙伴介绍这个。

昨晚我确实问了一个类似的问题,但从那时起我已经取得了一些进展。

3 个答案:

答案 0 :(得分:3)

此解决方案假设您的昆虫名称仅包含英文字母且没有数字,第一个字母为大写,剩余部分为小写。

data.frame(table(grep("[A-Z]{1}[a-z]+",stack(df1)[,1],value=TRUE)))
        Var1 Freq
1       Apis    4
2 Halictidae    2
3  Syrphidae    3

数据

df1<-
structure(list(ID = 1:10, Visit_Freq = c(1, 5, 1, 0, 0, 0, 0, 
2, 0, 0), Visitor_1 = c("Halictidae", "Syrphidae", "Apis", "<NA>", 
"<NA>", "<NA>", "<NA>", "Apis", "<NA>", "<NA>"), Visitor_2 = c("<NA>", 
"Halictidae", "<NA>", "<NA>", "<NA>", "<NA>", "<NA>", "Apis", 
"<NA>", "<NA>"), Visitor_3 = c("<NA>", "Syrphidae", "<NA>", "<NA>", 
"<NA>", "<NA>", "<NA>", "<NA>", "<NA>", "<NA>"), Visitor_4 = c("<NA>", 
"Syrphidae", "<NA>", "<NA>", "<NA>", "<NA>", "<NA>", "<NA>", 
"<NA>", "<NA>"), Visitor_5 = c("<NA>", "Apis", "<NA>", "<NA>", 
"<NA>", "<NA>", "<NA>", "<NA>", "<NA>", "<NA>")), .Names = c("ID", 
"Visit_Freq", "Visitor_1", "Visitor_2", "Visitor_3", "Visitor_4", 
"Visitor_5"), row.names = c(NA, -10L), class = "data.frame")

答案 1 :(得分:1)

使用我们的昆虫名称创建一个载体

insects <- c( "Apis", "Halictidae", "Syrphidae" )

您也可以使用

自动获取此信息
insects <- unique( unlist( DataSet[ 3:7 ] ) )
insects <- insects[ -( which ( insects == "<NA>" ) ) ]

然后创建一个获取访问次数的空变量

count <- NULL

然后你可以继续使用你拥有的东西,然后循环遍历昆虫的名字

for( i in insects ) 
    count <- c( count, sum( apply( DataSet[ 3:7 ], 2, 
                       function( x ) length( which( x == i) ) ) ) )
count
[1] 4 2 3

如果您愿意,可以将两者结合起来

insectCount <- data.frame( insects, count )
insectCount
     insects count
1       Apis     4
2 Halictidae     2
3  Syrphidae     3

请注意,昆虫的顺序会有所不同,具体取决于您是手动还是自动创建矢量。在任何一种情况下,计数都是相同的。

答案 2 :(得分:0)

我喜欢这些问题dplyr,因为一旦数据采用正确(整洁)的格式,问题就可以在一行中解决。要将数据转换为整洁格式,我们还需要一行(使用包gather()中的tidyr)。

我正在使用user227710定义的数据框here.请注意,它包含字符串&#34;&lt; NA&gt;&#34;而不是适当的R NA,所以过滤掉NA的线看起来有点奇怪。

实际工作由函数group_by()tally()完成。您告诉R如何对数据进行分组(此处为Species变量),然后tally()对其进行计数。

我理解,您并不想使用外部软件包,但学习如何使用tidyrdplyr对于定期处理数据的人来说绝对值得。

require(tidyr) # for gather()
require(dplyr) # for group_by() and tally()

# convert table into tidy (long) format
df_long <- gather(df1, Visitor, Species, Visitor_1:Visitor_5)
head(df_long)
##   ID Visit_Freq   Visitor    Species
## 1  1          1 Visitor_1 Halictidae
## 2  2          5 Visitor_1  Syrphidae
## 3  3          1 Visitor_1       Apis
## 4  4          0 Visitor_1       <NA>
## 5  5          0 Visitor_1       <NA>
## 6  6          0 Visitor_1       <NA>

# now count species, excluding the <NA> value
group_by(df_long, Species) %>%
    filter(Species != "<NA>") %>% 
    tally()
## Source: local data frame [3 x 2]
## 
##      Species  n
## 2       Apis  4
## 3 Halictidae  2
## 4  Syrphidae  3