我在R.相对较新。我正在开展一个项目,其中有一列ID(PMID),一列MESH术语,基本上是很多生物医学总结术语(MH),以及按顺序组织的年份列(EDAT_Year)。我的目标是创建一个向量,该向量包含每年MESH术语中特定单词的计数。基本上,如果一行包含单词(不是它在行中的次数,而是它的存在),它应该被计算并在向量中用年份分隔。
这是一个例子。假设这是数据帧:
PMID MH EDAT_Year
1 Male, Lung, Heart, Aneurysm 1978
2 Male, Male, Anemia, Lung 1978
3 Heart, Anemia, Adult 1980
4 Female, Heart, Blood, Acute 1980
5 Male, Blood, Adult, Lung 1980
6 Male, Kidney, Brain, Heart 1983
7 Male, Lung, Blood, Male 1983
然后,如果我要测试"男性",我希望输出
2 1 2
表示在1978年有2个观察结果包含"男性",1980年1个,1983年2个(无论它出现了多少次)。
我目前正在工作3年,但希望扩展到更多。我能够用以下3年手动完成这项工作(顺便提到1978年,1980年,1983年),其中我创建了多个列,如果它们属于那一年,则只包含MESH术语:
# count occurrences in the three years
disease_78 <- length(grep("\\Male\\>", total$MH_78))
disease_80 <- length(grep("\\Male\\>", total$MH_80))
disease_83 <- length(grep("\\Male\\>", total$MH_83))
但是现在我正在尝试编写一个函数,这样如果我输入一个短语,我会在一个向量中得到所有出现的内容,而不是每年手动复制和粘贴或有数百个列。这就是我到目前为止所做的:
# function of count occurences
count_fxn <- function(x)
{
# read in argument as character
phrase_to_count <- deparse(substitute(x))
# create a vector to store count values
count_occur <- numeric(0)
# a vector for how many years there are
num_years <- seq(1, 3, 1)
# loop through entire data frame
for (i in 1:length(total$PMID))
{
# loop through the three years
for(j in 1:length(num_years))
{
# if at least one occurence occurs in row cell, increment count
if (length(grep(phrase_to_count, total$MH[i]) > 0))
{
count_occur[j] <- count_occur[j] + 1
}
# if the next row's year is different than the current one's, move to
# next spot for next year in vector
if (total$EDAT_Year[i] != total$EDAT_Year[i+1])
{
j <- j + 1
}
# increment so go to next line to read in data
i <- i + 1
}
}
return(count_occur)
}
# using function
count_fxn(Male)
但这是我不断得到的错误:
Error in if (total$EDAT_Year[i] != total$EDAT_Year[i + 1]) { :
missing value where TRUE/FALSE needed
当我改变
if (total$EDAT_Year[i] != total$EDAT_Year[i + 1])
到
if (total$EDAT_Year[j] != total$EDAT_Year[j + 1])
我没有收到任何错误,相反,输出是
NA NA NA
什么时候应该是
3453 2343 5235
表示包含的观察数量&#34;男性&#34;其中,分别是1978年,1980年和1983年。
请指教。我还不是最强的编码器,而且我确定它可以在更短的时间内完成,我已经在这个工作了2个小时。
答案 0 :(得分:2)
您可以使用by()
。
with(df, lengths(by(MH, EDAT_Year, grep, pattern="Male")))
# EDAT_Year
# 1978 1980 1983
# 2 1 2
答案 1 :(得分:0)
如果你想计算每个&#34;字的出现次数&#34;在MH
每年,无需输入每个单词或创建单词列表,您可以按如下方式进行:
DF <- read.table(text="PMID MH EDAT_Year
1 Male,Lung,Heart,Aneurysm 1978
2 Male,Male,Anemia,Lung 1978
3 Heart,Anemia,Adult 1980
4 Female,Heart,Blood,Acute 1980
5 Male,Blood,Adult,Lung 1980
6 Male,Kidney,Brain,Heart 1983
7 Male,Lung,Blood,Male 1983", header=T)
DF <- DF %>%
#Convert MH column to nested list
dplyr::mutate(MH = strsplit(as.character(MH), ",")) %>%
#reashape data into tidy format
tidyr::unnest(MH) %>%
#eliminate duplicates to not count PMIDs with multiple identical entries in MH
unique() %>%
#count entries for each value in MH by year
reshape2::dcast(EDAT_Year ~ MH)
DF
结果:
EDAT_Year Acute Adult Anemia Aneurysm Blood Brain Female Heart Kidney Lung Male
1 1978 0 0 1 1 0 0 0 1 0 2 2
2 1980 1 2 1 0 2 0 1 2 0 1 1
3 1983 0 0 0 0 1 1 0 1 1 1 2