【问题标题】:R dataframe with values in the wrong columnsR数据框的值在错误的列中
【发布时间】:2021-07-02 17:18:12
【问题描述】:

我有一个像这样的数据框:

Name Characteristic_1 Characteristic_2 
Apple Yellow Italian
Pear British Yellow
Strawberries French Red
Blackberry Blue Austrian

如您所见,特征可以在不同的列中,具体取决于行。我想获得一个数据框,其中每列仅包含特定特征的值。

Name Characteristic_1 Characteristic_2 
Apple Yellow Italian
Pear  Yellow British
Strawberries Red French
Blackberry Blue Austrian

我的想法是使用 case_when 函数,但我想知道是否有更快的方法来实现相同的结果。

示例数据:

df <- structure(list(Name = c("Apple", "Pear", "Strawberries", "Blackberry"
), Characteristic_1 = c("Yellow", "British", "French", "Blue"
), Characteristic_2 = c("Italian", "Yellow", "Red", "Austrian"
)), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"
))

【问题讨论】:

  • 您是否有一些查找表来实际查看哪些特征属于 set1,哪些属于 set2。我怀疑在你的真实情况下,这些不会是颜色或国家名称。

标签: r dplyr tidyverse


【解决方案1】:

我怀疑有一种更简单的方法可以解决这个问题,但这里有一个可能的解决方案:

# Load the libraries
library(tidyverse)

# Load the data
df <- structure(list(Name = c("Apple", "Pear", "Strawberries", "Blackberry"
), Characteristic_1 = c("Yellow", "British", "French", "Blue"
), Characteristic_2 = c("Italian", "Yellow", "Red", "Austrian"
)), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"
))

# R has 657 built in colour names. You can see them using the `colours()` function.
# Chances are your colours are contained in this list.
# The `str_to_title()` function capitalizes every colour in the list
list_of_colours <- str_to_title(colours())
# If your colours are not contained in the list, add them using e.g.
# `list_of_colours <- c(list_of_colours, "Octarine")`

# Create a new dataframe ("df2") by taking the original dataframe ("df")
df2 <- df %>% 
# Create two new columns called "Colour" and "Origin" using `mutate()` with
# `ifelse` used to identify whether each word is in the list of colours.
# If the word is in the list of colours, add it to the "Colours" column, if
# it isn't, add it to the "Origin" column.
  mutate(Colour = ifelse(!is.na(str_extract(Characteristic_1, paste(list_of_colours, collapse = "|"))),
                       Characteristic_1, Characteristic_2),
         Origin = ifelse(is.na(str_extract(Characteristic_1, paste(list_of_colours, collapse = "|"))),
                         Characteristic_1, Characteristic_2)) %>% 
# Then select the columns you want
  select(Name, Colour, Origin)

df2
# A tibble: 4 x 3
#  Name         Colour Origin  
#  <chr>        <chr>  <chr>   
#1 Apple        Yellow Italian 
#2 Pear         Yellow British 
#3 Strawberries Red    French  
#4 Blackberry   Blue   Austrian

【讨论】:

    【解决方案2】:

    我认为还有一种更好的方法可以实现这一点,但目前这是我想到的一个解决方案:

    library(dplyr)
    library(stringr)
    
    df <- structure(list(Name = c("Apple", "Pear", "Strawberries", "Blackberry"
    ), Characteristic_1 = c("Yellow", "British", "French", "Blue"
    ), Characteristic_2 = c("Italian", "Yellow", "Red", "Austrian"
    )), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"
    ))
    
    df %>%
      mutate(char_1 = if_else(str_to_lower(Characteristic_1) %in% colours(distinct = TRUE), 
                              Characteristic_1, Characteristic_2), 
             char_2 = if_else(Characteristic_1 == char_1, Characteristic_2, Characteristic_1)) %>%
      select(-c(Characteristic_1, Characteristic_2))
    
    # A tibble: 4 x 3
      Name         char_1 char_2  
      <chr>        <chr>  <chr>   
    1 Apple        Yellow Italian 
    2 Pear         Yellow British 
    3 Strawberries Red    French  
    4 Blackberry   Blue   Austrian
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      相关资源
      最近更新 更多