簡體   English   中英

根據R中的兩列分配特定值

[英]Assign specific value based on two column in R

我有一個數據框,看起來像:

   Student_ID    Number  Position
    VB-123        10      2
    VB-456        15      5
    VB-789        25      25
    VB-889        12      2
    VB-965        15      7
    VB-758        45      9
    VB-245        25      25

我想添加新列並根據以下條件分配值:

  1. 如果只有Number在整個數據幀中重復,則分配A
  2. 如果只有Position在整個數據幀中重復,則分配B
  3. 如果NumberPosition都重復,則分配C
  4. 如果沒有重復,則分配D

輸出看起來像:

Student_ID    Number  Position   Assign
    VB-123        10      2      B
    VB-456        15      5      A
    VB-789        25      25     C
    VB-889        12      2      B
    VB-965        15      7      A
    VB-758        45      9      D
    VB-245        25      25     C

有了dplyr,

library(dplyr)

students <- data.frame(Student_ID = c("VB-123", "VB-456", "VB-789", "VB-889", "VB-965", "VB-758", "VB-245"), 
                       Number = c(10L, 15L, 25L, 12L, 15L, 45L, 25L), 
                       Position = c(2L, 5L, 25L, 2L, 7L, 9L, 25L))

students2 <- students %>% 
    mutate_at(vars(Number, Position), funs(n = table(.)[as.character(.)])) %>% 
    mutate(Assign = case_when(Number_n > 1 & Position_n > 1 ~ 'C', 
                              Number_n > 1 ~ 'A', 
                              Position_n > 1 ~ 'B', 
                              TRUE ~ 'D'))

students2
#>   Student_ID Number Position Number_n Position_n Assign
#> 1     VB-123     10        2        1          2      B
#> 2     VB-456     15        5        2          1      A
#> 3     VB-789     25       25        2          2      C
#> 4     VB-889     12        2        1          2      B
#> 5     VB-965     15        7        2          1      A
#> 6     VB-758     45        9        1          1      D
#> 7     VB-245     25       25        2          2      C

作為mutate_at行的替代方法,您可以使用add_count兩次,根據需要重命名。 要刪除中間列,請select(-matches('_n$'))

您可以通過分配子集來或多或少地復制基礎中的邏輯:

students2 <- cbind(students, lapply(students[2:3], function(x) table(x)[as.character(x)]))
students2$Assign <- 'D'
students2$Assign[students2$Number.Freq > 1 & students2$Position.Freq > 1] <- 'C'
students2$Assign[students2$Number.Freq > 1 & students2$Position.Freq == 1] <- 'A'
students2$Assign[students2$Number.Freq == 1 & students2$Position.Freq > 1] <- 'B'
students2[4:7] <- NULL

students2
#>   Student_ID Number Position Assign
#> 1     VB-123     10        2      B
#> 2     VB-456     15        5      A
#> 3     VB-789     25       25      C
#> 4     VB-889     12        2      B
#> 5     VB-965     15        7      A
#> 6     VB-758     45        9      D
#> 7     VB-245     25       25      C

這是使用base R的選項。 按照evaluateatin('l1')的順序創建列名list ,預分配'D'以在'dat'中創建'Assign'列,循環遍歷'l1'的序列,基於數據列的子集在'l1'中的列名稱上,使用duplicated查找重復元素並將'Assign'列重新分配給相應的LETTER

l1 <- list("Number", "Position", c("Number", "Position"))
dat$Assign <- rep("D", nrow(dat))
for(i in seq_along(l1)){
    df <- dat[l1[[i]]]  
    i1 <- duplicated(df)|duplicated(df, fromLast = TRUE)
    dat$Assign <- replace(dat$Assign, i1, LETTERS[i])
}   

- 輸出

dat
#  Student_ID Number Position Assign
#1     VB-123     10        2      B
#2     VB-456     15        5      A
#3     VB-789     25       25      C
#4     VB-889     12        2      B
#5     VB-965     15        7      A
#6     VB-758     45        9      D
#7     VB-245     25       25      C

使用的解決方案。

library(dplyr)

dat2 <- dat %>% count(Number)
dat3 <- dat %>% count(Position)
dat4 <- dat %>% count(Number, Position)

dat5 <- dat %>%
  left_join(dat2, by = "Number") %>%
  left_join(dat3, by = "Position") %>%
  left_join(dat4, by = c("Number", "Position")) %>%
  mutate(Assign = case_when(
    n > 1               ~ "C",
    n.x > 1 & n.y == 1  ~ "A",
    n.y > 1 & n.x == 1  ~ "B",
    TRUE                ~ "D"
  )) %>%
  select(-n.x, -n.y, -n)
dat5
#   Student_ID Number Position Assign
# 1     VB-123     10        2      B
# 2     VB-456     15        5      A
# 3     VB-789     25       25      C
# 4     VB-889     12        2      B
# 5     VB-965     15        7      A
# 6     VB-758     45        9      D
# 7     VB-245     25       25      C

數據

dat <- read.table(text = "Student_ID    Number  Position
    'VB-123'        10      2
    'VB-456'        15      5
    'VB-789'        25      25
    'VB-889'        12      2
    'VB-965'        15      7
    'VB-758'        45      9
    'VB-245'        25      25",
                  header = TRUE, stringsAsFactors = FALSE)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM