通过条件查找在 R 数据框中创建新变量
Create new variable in R data frame by conditional lookup
我想在 R 数据框中创建一个新变量,方法是将现有列用作同一 table 中另一列的查找值。例如,在以下数据框中:
df = data.frame(
pet = c("smalldog", "mediumdog", "largedog",
"smallcat", "mediumcat", "largecat"),
numPets = c(1, 2, 3, 4, 5, 6)
)
> df
pet numPets
1 smalldog 1
2 mediumdog 2
3 largedog 3
4 smallcat 4
5 mediumcat 5
6 largecat 6
我想创建一个名为 numEnemies 的新列,对于小型动物,它等于零,但对于中型和大型动物,它等于相同大小但不同物种的动物数量。我想以此结束:
pet numPets numEnemies
1 smalldog 1 0
2 mediumdog 2 5
3 largedog 3 6
4 smallcat 4 0
5 mediumcat 5 2
6 largecat 6 3
我尝试这样做的方法是使用条件逻辑生成一个字符变量,然后我可以用它从同一个数据框中查找我想要的最终值,这让我来到这里:
calculateEnemies <- function(df) {
ifelse(grepl('small', df$pet), 0,
ifelse(grepl('dog', df$pet), gsub('dog', 'cat', df$pet),
ifelse(grepl('cat', df$pet),
gsub('cat', 'dog', df$pet), NA)))
}
df$numEnemies <- calculateEnemies(df)
> df
pet numPets numEnemies
1 smalldog 1 0
2 mediumdog 2 mediumcat
3 largedog 3 largecat
4 smallcat 4 0
5 mediumcat 5 mediumdog
6 largecat 6 largedog
我想修改此函数以使用新生成的字符串根据 df$pet 中的相应值从 df$numPets 中查找值。我也愿意接受一种更好的方法,这种方法也可以概括。
下面是我将如何使用 data.table
包
来解决这个问题
library(data.table)
setDT(df)[, numEnemies := rev(numPets), by = sub(".*(large|medium).*", "\1", pet)]
df[grep("^small", pet), numEnemies := 0L]
# pet numPets numEnemies
# 1: smalldog 1 0
# 2: mediumdog 2 5
# 3: largedog 3 6
# 4: smallcat 4 0
# 5: mediumcat 5 2
# 6: largecat 6 3
我基本上所做的是首先在整个数据集上创建 medium
和 large
组,然后反转每个组中的值。
然后,当 grep("^small", pet)
时,我将 0
分配给 numPets
中的所有值。
这应该是非常有效和稳健的,因为它适用于任意数量的动物,而且您实际上不需要先验地知道动物的名字。
我想在 R 数据框中创建一个新变量,方法是将现有列用作同一 table 中另一列的查找值。例如,在以下数据框中:
df = data.frame(
pet = c("smalldog", "mediumdog", "largedog",
"smallcat", "mediumcat", "largecat"),
numPets = c(1, 2, 3, 4, 5, 6)
)
> df
pet numPets
1 smalldog 1
2 mediumdog 2
3 largedog 3
4 smallcat 4
5 mediumcat 5
6 largecat 6
我想创建一个名为 numEnemies 的新列,对于小型动物,它等于零,但对于中型和大型动物,它等于相同大小但不同物种的动物数量。我想以此结束:
pet numPets numEnemies
1 smalldog 1 0
2 mediumdog 2 5
3 largedog 3 6
4 smallcat 4 0
5 mediumcat 5 2
6 largecat 6 3
我尝试这样做的方法是使用条件逻辑生成一个字符变量,然后我可以用它从同一个数据框中查找我想要的最终值,这让我来到这里:
calculateEnemies <- function(df) {
ifelse(grepl('small', df$pet), 0,
ifelse(grepl('dog', df$pet), gsub('dog', 'cat', df$pet),
ifelse(grepl('cat', df$pet),
gsub('cat', 'dog', df$pet), NA)))
}
df$numEnemies <- calculateEnemies(df)
> df
pet numPets numEnemies
1 smalldog 1 0
2 mediumdog 2 mediumcat
3 largedog 3 largecat
4 smallcat 4 0
5 mediumcat 5 mediumdog
6 largecat 6 largedog
我想修改此函数以使用新生成的字符串根据 df$pet 中的相应值从 df$numPets 中查找值。我也愿意接受一种更好的方法,这种方法也可以概括。
下面是我将如何使用 data.table
包
library(data.table)
setDT(df)[, numEnemies := rev(numPets), by = sub(".*(large|medium).*", "\1", pet)]
df[grep("^small", pet), numEnemies := 0L]
# pet numPets numEnemies
# 1: smalldog 1 0
# 2: mediumdog 2 5
# 3: largedog 3 6
# 4: smallcat 4 0
# 5: mediumcat 5 2
# 6: largecat 6 3
我基本上所做的是首先在整个数据集上创建 medium
和 large
组,然后反转每个组中的值。
然后,当 grep("^small", pet)
时,我将 0
分配给 numPets
中的所有值。
这应该是非常有效和稳健的,因为它适用于任意数量的动物,而且您实际上不需要先验地知道动物的名字。