Eva*_*ens 27
case_when(),2016年5月被添加到dplyr,以类似的方式解决了这个问题memisc::cases().
例如:
library(dplyr)
mtcars %>%
mutate(category = case_when(
.$cyl == 4 & .$disp < median(.$disp) ~ "4 cylinders, small displacement",
.$cyl == 8 & .$disp > median(.$disp) ~ "8 cylinders, large displacement",
TRUE ~ "other"
)
)
Run Code Online (Sandbox Code Playgroud)
截至dplyr 0.7.0,
mtcars %>%
mutate(category = case_when(
cyl == 4 & disp < median(disp) ~ "4 cylinders, small displacement",
cyl == 8 & disp > median(disp) ~ "8 cylinders, large displacement",
TRUE ~ "other"
)
)
Run Code Online (Sandbox Code Playgroud)
Hen*_*ico 26
cases从memisc包中查看功能.它使用两种不同的方式来实现案例功能.从包中的示例:
z1=cases(
"Condition 1"=x<0,
"Condition 2"=y<0,# only applies if x >= 0
"Condition 3"=TRUE
)
Run Code Online (Sandbox Code Playgroud)
其中x和y是两个矢量.
Mar*_*rek 21
如果你有,factor那么你可以通过标准方法改变等级:
df <- data.frame(name = c('cow','pig','eagle','pigeon'),
stringsAsFactors = FALSE)
df$type <- factor(df$name) # First step: copy vector and make it factor
# Change levels:
levels(df$type) <- list(
animal = c("cow", "pig"),
bird = c("eagle", "pigeon")
)
df
# name type
# 1 cow animal
# 2 pig animal
# 3 eagle bird
# 4 pigeon bird
Run Code Online (Sandbox Code Playgroud)
您可以编写简单的函数作为包装器:
changelevels <- function(f, ...) {
f <- as.factor(f)
levels(f) <- list(...)
f
}
df <- data.frame(name = c('cow','pig','eagle','pigeon'),
stringsAsFactors = TRUE)
df$type <- changelevels(df$name, animal=c("cow", "pig"), bird=c("eagle", "pigeon"))
Run Code Online (Sandbox Code Playgroud)
Pra*_*ani 17
以下是使用该switch语句的方法:
df <- data.frame(name = c('cow','pig','eagle','pigeon'),
stringsAsFactors = FALSE)
df$type <- sapply(df$name, switch,
cow = 'animal',
pig = 'animal',
eagle = 'bird',
pigeon = 'bird')
> df
name type
1 cow animal
2 pig animal
3 eagle bird
4 pigeon bird
Run Code Online (Sandbox Code Playgroud)
这样做的一个缺点是你必须继续animal为每个项目写下类别名称(等).在语法上更方便的是能够如下定义我们的类别(参见非常类似的问题如何在R中的数据框中添加列)
myMap <- list(animal = c('cow', 'pig'), bird = c('eagle', 'pigeon'))
Run Code Online (Sandbox Code Playgroud)
我们想以某种方式"反转"这种映射.我编写自己的invMap函数:
invMap <- function(map) {
items <- as.character( unlist(map) )
nams <- unlist(Map(rep, names(map), sapply(map, length)))
names(nams) <- items
nams
}
Run Code Online (Sandbox Code Playgroud)
然后按如下方式反转上面的地图:
> invMap(myMap)
cow pig eagle pigeon
"animal" "animal" "bird" "bird"
Run Code Online (Sandbox Code Playgroud)
然后很容易使用它来添加type数据框中的列:
df <- transform(df, type = invMap(myMap)[name])
> df
name type
1 cow animal
2 pig animal
3 eagle bird
4 pigeon bird
Run Code Online (Sandbox Code Playgroud)
Gre*_*min 14
Imho,最简单和通用的代码:
dft=data.frame(x = sample(letters[1:8], 20, replace=TRUE))
dft=within(dft,{
y=NA
y[x %in% c('a','b','c')]='abc'
y[x %in% c('d','e','f')]='def'
y[x %in% 'g']='g'
y[x %in% 'h']='h'
})
Run Code Online (Sandbox Code Playgroud)
小智 14
我没有看到"切换"的提议.代码示例(运行它):
x <- "three";
y <- 0;
switch(x,
one = {y <- 5},
two = {y <- 12},
three = {y <- 432})
y
Run Code Online (Sandbox Code Playgroud)
有一个switch声明,但我似乎永远不会按照我认为应该的方式让它工作.由于您没有提供示例,我将使用因子变量创建一个:
dft <-data.frame(x = sample(letters[1:8], 20, replace=TRUE))
levels(dft$x)
[1] "a" "b" "c" "d" "e" "f" "g" "h"
Run Code Online (Sandbox Code Playgroud)
如果在适合重新分配的顺序中指定所需的类别,则可以使用因子或数字变量作为索引:
c("abc", "abc", "abc", "def", "def", "def", "g", "h")[dft$x]
[1] "def" "h" "g" "def" "def" "abc" "h" "h" "def" "abc" "abc" "abc" "h" "h" "abc"
[16] "def" "abc" "abc" "def" "def"
dft$y <- c("abc", "abc", "abc", "def", "def", "def", "g", "h")[dft$x] str(dft)
'data.frame': 20 obs. of 2 variables:
$ x: Factor w/ 8 levels "a","b","c","d",..: 4 8 7 4 6 1 8 8 5 2 ...
$ y: chr "def" "h" "g" "def" ...
Run Code Online (Sandbox Code Playgroud)
后来我才知道有两种不同的开关功能.它不是通用功能,但您应该将其视为switch.numeric或者switch.character.如果你的第一个参数是一个R'因子',你就会得到switch.numeric行为,这很可能会引起问题,因为大多数人都会看到显示为字符的因素,并做出错误的假设,即所有函数都将处理它们.
您可以使用汽车套餐中的重新编码:
library(ggplot2) #get data
library(car)
daimons$new_var <- recode(diamonds$clarity , "'I1' = 'low';'SI2' = 'low';else = 'high';")[1:10]
Run Code Online (Sandbox Code Playgroud)
小智 5
我不喜欢这些,他们不清楚读者或潜在用户.我只是使用匿名函数,语法不像case语句那样光滑,但评估类似于case语句而不是那么痛苦.这也假设您在定义变量的位置进行评估.
result <- ( function() { if (x==10 | y< 5) return('foo')
if (x==11 & y== 5) return('bar')
})()
Run Code Online (Sandbox Code Playgroud)
所有这些()都是封闭和评估匿名函数所必需的.
我在你所指的那些情况下使用switch()。它看起来像一个控制语句,但实际上它是一个函数。对表达式求值,并根据该值返回列表中的相应项。
switch 以两种不同的方式工作,具体取决于第一个参数的计算结果是字符串还是数字。
下面是一个简单的字符串示例,它解决了将旧类别折叠为新类别的问题。
对于字符串形式,在命名值之后有一个未命名的参数作为默认值。
newCat <- switch(EXPR = category,
cat1 = catX,
cat2 = catX,
cat3 = catY,
cat4 = catY,
cat5 = catZ,
cat6 = catZ,
"not available")
Run Code Online (Sandbox Code Playgroud)