我正在尝试基于另一列创建新列,使用case_when
根据每一行的值提供不同的输出。
我从df <- data.frame(a=c("abc", "123", "abc", "123"))
开始
并希望像这样生成新列b
#> a b
#> 1 abc letter
#> 2 123 number
#> 3 abc letter
#> 4 123 number
我已经尝试过df %>% mutate(b = case_when(startsWith(a, "a") ~ "letter", startsWith(a, "1") ~ "number"))
,但只给出了一个错误。有人可以告诉我如何根据a列中行的第一个字母为b列获取不同的值吗?
答案 0 :(得分:1)
根据?startsWith
x-被视为“开始”的字符串的向量。
因此,startsWith
期望该类为character
,这里是factor
类。将其转换为character
类可以解决问题
library(dplyr)
df %>%
mutate(b = case_when(startsWith(as.character(a), "a") ~ "letter",
TRUE ~ "number"))
# a b
#1 abc letter
#2 123 number
#3 abc letter
#4 123 number
data.frame
的默认行为是stringsAsFactors = TRUE
。如果我们指定stringsAsFactors = FALSE
,则'a'列将为character
类
另一种选择是str_detect
,可通过检查字符串开头(^
)的字符是否是数字([0-9]
)来创建逻辑表达式
library(stringr)
library(dplyr)
df %>%
mutate(b = c("letter", "number")[1+str_detect(a, "^[0-9]")])
# a b
#1 abc letter
#2 123 number
#3 abc letter
# 123 number
答案 1 :(得分:0)
由于这里只有两种情况,因此您只能使用if_else()
。考虑到您要运行的测试,正则表达式似乎更合适。关键是^
指定字符串的开头,[:alpha:]
匹配不区分大小写的字母。
library(tidyverse)
df <- data.frame(a=c("abc", "123", "abc", "123"))
df %>% mutate(
b = a %>% str_detect("^[:alpha:]") %>% if_else("letter", "number")
)
#> a b
#> 1 abc letter
#> 2 123 number
#> 3 abc letter
#> 4 123 number
由reprex package(v0.3.0)于2019-09-29创建
正如@akrun指出的那样,因素与字符之间存在问题-您确定这是适用于您的用例的示例,即您的真实数据是否在因素中?幸运的是,str_detect()
的任何一种方式都一样好。