如何选择具有2个特定条件的行,其中一个条件取决于另一个

时间:2017-11-03 21:41:21

标签: r

您好我有一个看起来像这样的数据框(实际的数据框有更多的行和更多的列,但这些是我现在特别关注的列):

     Male_ID   Mate_ID  Year  Pair_Number
  1        A         B  1987            1
  2        A         C  1987            2
  3        E         D  1988            2
  4        E         F  1990            1

我正在尝试选择包含男性交配的第一个配偶ID的行。我想选择年份值最低的行和给定年份内最低的Pair_Number,所以我要确保选择第一行和第三行。

我试过这段代码:

        d <- ddply(dataframe, .(Male_ID), summarise, Year = min(Year), Pair_Number = min(Pair_Number))
        results <- left_join(d, dataframe, by = c("Male_ID", "Year", "Pair_Number))

但第一段代码让我回答:

          Male_ID   Year   Pair_Number
       1        A   1987            1
       2        E   1988            1

第1行是正确的,但第二行不是。在1988年,男性E没有Pair_Number等于1。

我想要这个:

          Male_ID   Year  Pair_Number
       1        A   1987            1
       2        E   1988            2

谢谢!

3 个答案:

答案 0 :(得分:1)

仅使用data.table 首先是数据集。

empty_list = []    ## equivalent to R vector

for i in range(10):
    empty_list.append(i)

print(empty_list)   ## now [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

现在代码。

base R

请注意,我创建了变量(类dataframe <- read.table(text = " Male_ID Mate_ID Year Pair_Number 1 A B 1987 1 2 A C 1987 2 3 E D 1988 2 4 E F 1990 1 ", header = TRUE) sp <- split(dataframe, dataframe$Male_ID) result <- lapply(sp, function(x) x[which.min(x$Year), ]) result <- do.call(rbind, result) row.names(result) <- NULL rm(sp) # tidy up result # Male_ID Mate_ID Year Pair_Number #1 A B 1987 1 #2 E D 1988 2 只是为了使代码更具可读性。也许你可以跳过那部分并做

list

其次是代码。但我发现可读代码是更好的代码。

答案 1 :(得分:1)

使用dplyr并将所有变量保留在最终结果中(如果需要,可以删除):

df <- read.table(text = "Male_ID   Mate_ID  Year  Pair_Number
1        A         B  1987            1
2        A         C  1987            2
3        E         D  1988            2
4        E         F  1990            1", header = TRUE, stringsAsFactors = FALSE)

library(dplyr)

df %>% 
  group_by(Male_ID) %>%
  arrange(Year, Pair_Number, .by_group = TRUE) %>%
  slice(1)

#> # A tibble: 2 x 4
#> # Groups:   Male_ID [2]
#>   Male_ID Mate_ID  Year Pair_Number
#>     <chr>   <chr> <int>       <int>
#> 1       A       B  1987           1
#> 2       E       D  1988           2

答案 2 :(得分:0)

尝试:

Linux

给出了:

df %>% 
  group_by(Male_ID, Year) %>% 
  filter(Pair_Number == min(Pair_Number)) %>% 
  ungroup() %>% 
  distinct(Male_ID, .keep_all = TRUE)
  1. # A tibble: 2 x 4 Male_ID Mate_ID Year Pair_Number <fctr> <fctr> <int> <int> 1 A B 1987 1 2 E D 1988 2 Male_ID
  2. 分组
  3. 按最小Year
  4. 过滤这些群组
  5. 取消组合
  6. 返回每个不同Pair_Number
  7. 的第一行