所以我有两个数据帧,第一个是这样的,有不同种类的海鱼的名字(相同的物种在整个数据帧中重复,总共有74610个条目),它们各自的BIN (一种基于聚类算法分配给物种的序列号),以及一个空列(grade),我想根据第二个数据帧的条件填充它:
dataframe1
species BIN grade
1. Tilapia guineensis | BOLD:AAL5979 | NA
2. Tilapia zillii | BOLD:AAB9042 | NA
3. Fundulus rubrifrons | BOLD:AAI7245 | NA
4. Eutrigla gurnardus | BOLD:AAC0262 | NA
5. Sprattus sprattus | BOLD:AAE9187 | NA
6. Gadus morhua | BOLD:ACF1143 | NA
第二个dataframe包含物种(这次只重复一次,总共只有7633个条目)和分配给每个物种的垃圾箱数量:
dataframe2
species bin_per_species BIN
1. Abalistes filamentosus | 1 | BOLD:AAD4738
2. Abalistes stellaris | 2 | BOLD:AAD4739,BOLD:ACK7828
3. Abalistes stellatus | 2 | BOLD:AAD4739,BOLD:ACK7828
4. Ablabys binotatus | 1 | BOLD:AAF8834
5. Ablennes hians | 2 | BOLD:AAC1231,BOLD:AAB9824
6. Abramis brama | 1 | BOLD:AAC8592
我想要做的基本上是在dataframe1中填充grade列,考虑到在dataframe2中分配给每个物种的箱数。例如,如果在dataframe2中一个物种有bin_per_species==1,我想要指定等级"A",但如果dataframe2中的一个物种有一个bin_per_species>1,我想指定等级"C“。
我尝试使用%in%函数,因为我不能使用"==“,因为它们有不同的长度。
尝试失败
dataframe1$grade[(as.character(dataframe1$species)%in%as.character(dataframe2$species))[dataframe2$bin_per_species==1]]="A"
我希望dataframe1会根据条件填充,但当我尝试上面的代码时,它只会用等级"A“填充每个单元格。如果我在表达我的问题时感到困惑,我很抱歉,但提前感谢您的回复。
发布于 2019-06-03 05:46:44
不幸的是,您的两个数据帧不是很有帮助,但我认为可以从第二个数据帧向后工作,以获得更具代表性的数据。根据您的评论,第一个数据帧可以包含具有不同BIN
的相同species
。
# A tibble: 9 x 3
species BIN grade
<chr> <chr> <int>
1 Abalistes filamentosus BOLD:AAD4738 NA
2 Abalistes stellaris BOLD:AAD4739 NA
3 Abalistes stellatus BOLD:AAD4739 NA
4 Ablabys binotatus BOLD:AAF8834 NA
5 Ablennes hians BOLD:AAC1231 NA
6 Abramis brama BOLD:AAC8592 NA
7 Abalistes stellaris BOLD:ACK7828 NA
8 Abalistes stellatus BOLD:ACK7828 NA
9 Ablennes hians BOLD:AAB9824 NA
第二个数据帧df2
保持不变。
使用一个数据帧
如果我没弄错的话,你真的不需要第二个数据帧。相反,您可以这样做,即根据species
和进行分组,并根据每个组的大小n()
给每个组一个等级
df1 %>%
group_by(species) %>%
mutate(grade = ifelse(n() == 1, "A", "C"))
#### OUTPUT ####
# A tibble: 9 x 3
# Groups: species [6]
species BIN grade
<chr> <chr> <chr>
1 Abalistes filamentosus BOLD:AAD4738 A
2 Abalistes stellaris BOLD:AAD4739 C
3 Abalistes stellatus BOLD:AAD4739 C
4 Ablabys binotatus BOLD:AAF8834 A
5 Ablennes hians BOLD:AAC1231 C
6 Abramis brama BOLD:AAC8592 A
7 Abalistes stellaris BOLD:ACK7828 C
8 Abalistes stellatus BOLD:ACK7828 C
9 Ablennes hians BOLD:AAB9824 C
使用两个数据帧
如果出于某种原因,您需要使用df1
和df2
,我认为最直接的方法是在species
上连接这两个数据帧,然后根据bin_per_species
的值修改grade
full_join(df1, df2, by = "species") %>%
mutate(grade = case_when(bin_per_species == 1 ~ "A",
bin_per_species == 2 ~ "B",
bin_per_species > 2 ~ "C",
)) %>%
select(1:3)
#### OUTPUT ####
# A tibble: 9 x 3
species BIN.x grade
<chr> <chr> <chr>
1 Abalistes filamentosus BOLD:AAD4738 A
2 Abalistes stellaris BOLD:AAD4739 B
3 Abalistes stellatus BOLD:AAD4739 B
4 Ablabys binotatus BOLD:AAF8834 A
5 Ablennes hians BOLD:AAC1231 B
6 Abramis brama BOLD:AAC8592 A
7 Abalistes stellaris BOLD:ACK7828 B
8 Abalistes stellatus BOLD:ACK7828 B
9 Ablennes hians BOLD:AAB9824 B
我包含了case_when()
,以防您拥有的不只是"A“和"C”这两个等级。您也可以在"one dataframe“解决方案中使用它。如果你真的只有这两个等级,那么你可以用ifelse()
来简化事情
full_join(df1, df2, by = "species") %>%
mutate(grade = ifelse(bin_per_species == 1, "A", "C")) %>%
select(1:3)
发布于 2019-06-03 01:37:27
欢迎
请检查这是否有效,并查看dput()函数。
library(tidyverse)
df <- tribble(~species,~BIN,
"A",1,
"B",2,
"B",3,
"B",4)
df %>%
group_by(species) %>%
summarise(count_bins = n()) %>%
mutate(grade = if_else(count_bins > 1,
"C",
"A")) %>%
right_join(df)
发布于 2019-06-03 02:30:08
我简化了你的问题,以便我测试它,如果这对你无效,请通知我。我把我的简单数据帧放在里面,这样你就可以看到我的进程了。
df1 <- data.frame(
species <- c('a', 'b', 'c', 'd'),
grade <- c(NA, NA, NA, NA)
)
colnames(df1) <- c('species', 'grade')
df2 <- data.frame(
species <- c('a', 'b', 'c', 'd'),
bin_per_species <- c(1, 2, 2, 1)
)
colnames(df2) <- c('species', 'bin_per_species')
df1[species %in% df2[which(df2[, 'bin_per_species'] == 2), 'species'], 'grade'] <- 'A'
https://stackoverflow.com/questions/56417082
复制相似问题