我有多个项目的数据,每个项目都由一个团队组成。我有关于他们的等级和性别的信息,如下:
df <- read.table(header = TRUE, text = 'Project GenderA RankA GenderB RankB GenderC RankC
100 1 3 0 1 1 2
200 1 2 1 2 NA NA
300 0 3 1 3 0 2
400 0 1 NA NA NA NA
500 1 1 0 2 1 1')
对于每个项目,我希望R创建一个在团队中具有最高排名的新变量以及该人的性别。
Project GenderA RankA GenderB RankB GenderC RankC HighGen HighRank
100 1 3 0 1 1 2 1 3
我可以用pmax获得最高等级:
df<-cbind(df,
HighRank = pmax(df$RankA, df$RankB, df$RankC))
但这仅适用于完整的项目(即没有NAs),并且不与性别列相关联。两种方法最好的方法是什么?
答案 0 :(得分:9)
这是一个自以为是的答案,但一次难以做到的原因是您的数据不够整洁。这意味着在这种情况下,您希望每行有一个观察。我给出了整洁的&#39;表示和使用dplyr
包的解决方案:
library(dplyr)
df <- read.table(header = TRUE, text = 'Project Gender Rank order
100 1 3 A
100 0 1 B
100 1 2 C
200 1 2 A
200 1 2 B
200 NA NA C
300 0 3 A
300 1 3 B
300 0 2 C')
df %>% group_by(Project) %>% arrange(-Rank) %>% slice(1) %>% ungroup()
为了解释最后一行,你按项目分组,按等级对这些项目中的所有分数进行排序,然后过滤第一行,最后,为了好的衡量,你取消组合,这意味着你忘了&#39;分组。您的输出是每个项目的最高得分记录,包括它的得分,性别。请注意,我还添加了一个新变量&#39; order&#39;,以反映数据在&#39; rankA&#39;下得分的事实。或者&#39; rankB&#39;等等。
输出:
| Project| Gender| Rank|order |
|-------:|------:|----:|:-----|
| 100| 1| 3|A |
| 300| 0| 3|A |
| 200| 1| 2|A |
也可以将数据分成整齐的表示,但您可能想要查看您首先输入数据的方式。这是为了整洁,但对于广泛的阅读,你可以看看http://vita.had.co.nz/papers/tidy-data.pdf。
感谢Gregor的评论,这里有一种方法可以将您的数据帧转换为更整洁的表示(使用包tidyr
)
library(tidyr)
df <- read.table(header = TRUE, text = 'Project GenderA RankA GenderB RankB GenderC RankC
100 1 3 0 1 1 2
200 1 2 1 2 NA NA
300 0 3 1 3 0 2
400 0 1 NA NA NA NA
500 1 1 0 2 1 1')
df %>% gather(key = key, value = value, -Project) %>% separate(key, into = c("variable", "order"), sep = -2) %>% spread(key = variable, value = value)
输出:
| Project|order | Gender| Rank|
|-------:|:-----|------:|----:|
| 100|A | 1| 3|
| 100|B | 0| 1|
| 100|C | 1| 2|
| 200|A | 1| 2|
| 200|B | 1| 2|
| 200|C | NA| NA|
| 300|A | 0| 3|
| 300|B | 1| 3|
| 300|C | 0| 2|
| 400|A | 0| 1|
| 400|B | NA| NA|
| 400|C | NA| NA|
| 500|A | 1| 1|
| 500|B | 0| 2|
| 500|C | 1| 1|
然后,您可以将其提供给第一部分中的公式以获得解决方案。