如何在R中找到基于用户定义层次结构的向量的最大字符?
我有一个变量,比如Code
,我想对其施加层次结构,以便MSP<1A<1B<1C<2A<2B<2C<…<7C。我想在包含这些元素的向量上应用一个极大值函数。虽然对于那些形式为[数字][字母]的字符没有问题,但对于"MSP"有一个问题。在R中,max("2A","MSP")给出"MSP",但我希望它是"2A"。
换句话说,R会这样对它进行排序:1A<…MSP。这是因为在R中,层次结构是"整数<双&>
Dataframe:
No<-rep(c(1,2,3),c(4,4,3))
Date<-rep(c("05/09/2013","20/05/2013","23/05/2013","28/05/2013","03/06/2013"),c(2,2,2,2,3))
Time<-rep(c("14:15:00","09:40:00","14:30:00","13:10:00","08:45:00"),c(2,1,3,2,3))
Code<-c("MSP","3A","5B",NA,NA,NA,"7C","3B","MSP","MSP",NA)
df<-data.frame(No,Date,Time,Code,stringsAsFactors=FALSE)
df$Date<-dmy(df$Date)
df$Time<-hms(df$Time)
df
# No Date Time Code
# 1 1 2013-09-05 14H 15M 0S MSP
# 2 1 2013-09-05 14H 15M 0S 3A
# 3 1 2013-05-20 9H 40M 0S 5B
# 4 1 2013-05-20 14H 30M 0S <NA>
# 5 2 2013-05-23 14H 30M 0S <NA>
# 6 2 2013-05-23 14H 30M 0S <NA>
# 7 2 2013-05-28 13H 10M 0S 7C
# 8 2 2013-05-28 13H 10M 0S 3B
# 9 3 2013-06-03 8H 45M 0S MSP
# 10 3 2013-06-03 8H 45M 0S MSP
# 11 3 2013-06-03 8H 45M 0S <NA>
我的代码:我想在每个No和Date中对Code
(基于用户定义的排名)取最大值。因此,共享相同No和相同Date的行将具有相同的Code。因此,我先将其分组。
ifelse
函数创建了一个名为CodeAnother
的新变量。- 如果至少有一个"MSP"而不是所有元素都是"MSP"
- Yes:通过排除"MSP"取最大函数
No:按常规方式取max函数
library(dplyr) dfnew<-df %>% group_by(No,Date) %>% mutate(IndicatorMSP=(Code=="MSP" & !is.na(Code))) %>% mutate(CodeNo=sum(!is.na(Code))) %>% mutate(CodeAnother=ifelse(sum(IndicatorMSP)>=1 & sum(IndicatorMSP)<CodeNo, max(Code[!(Code=="MSP") & !is.na(Code)]), max(Code[!is.na(Code)])))
我想知道是否有一个更好的方法来实现这个使用更好的代码。
因素,这一次,是你的朋友:
重新排序字母的例子:
factoringVariable <- sample(letters)
> factoringVariable
[1] "z" "k" "p" "s" "f" "v" "j" "b" "o" "l" "u" "m" "w" "c" "n" "t" "r" "x" "a" "i" "y" "q" "h" "d" "e" "g"
> sort(factor(letters,levels = factoringVariable))
[1] z k p s f v j b o l u m w c n t r x a i y q h d e g
所以在你的情况下:
factoringVariable <- c('MSP', sort(unlist(outer(1:7,LETTERS[1:3],paste0))))
> factoringVariable
[1] "MSP" "1A" "1B" "1C" "2A" "2B" "2C" "3A" "3B" "3C" "4A" "4B" "4C" "5A" "5B" "5C" "6A" "6B" "6C" "7A"
[21] "7B" "7C"
现在我已经设置好了我的顺序:
df$Code <- factor(df$Code, levels = factoringVariable)
然后你可以使用top_n
函数在dplyr(与-1得到底部1)
library(dplyr)
dfnew<-df %>%
group_by(No,Date) %>%
top_n(-1,Code)
输出:> dfnew
Source: local data frame [5 x 4]
Groups: No, Date [4]
No Date Time Code
<dbl> <chr> <chr> <fctr>
1 1 05/09/2013 14:15:00 MSP
2 1 20/05/2013 09:40:00 5B
3 2 28/05/2013 13:10:00 3B
4 3 03/06/2013 08:45:00 MSP
5 3 03/06/2013 08:45:00 MSP
编辑:我现在意识到你想分配所有的最大值,在这种情况下,我们不能使用top_n
:
library(dplyr)
dfnew<-df %>%
group_by(No,Date) %>%
mutate(CodeAll = sort(Code, partial = 1)[1])
编辑2:实际上你可以通过使用部分排序来加快它的速度(如果你需要速度),因为无论如何你只会取第一个