在 R 中有条件地更改变量中的值
Changing values in variables conditionally in R
Romance Horror Comedy Keyword
0 1 1 lol
1 0 0 love
0 0 1 lol
1 1 0 omg
大家好,我有一个像上面这样的数据集,我会用R来工作。我想要的是这样的:
如果keyword="lol",则喜剧=1,其他=0
如果关键字=“omg”,则恐怖=1,其他=0
If keyword= "love", make Romance=1, others=0
实际上,我试过 ifelse 语句,但没有用。顺便提一下,我有大约 200 个案例和 6 个变量。暂时谢谢了。
将前三列的列值更改为 1
df1[1:3] <- 0
然后,创建一个命名向量以匹配列名
nm1 <- setNames(c("Comedy", "Romance", "Horror"), c("lol", "love", "omg"))
根据'Keyword'的替换值,使用向量match
'df1'的列名得到列索引,cbind
用行索引,使用 row/column 索引的矩阵将数据集中的那些元素分配给 1
df1[1:3][cbind(seq_len(nrow(df1)), match(nm1[df1$Keyword], names(df1)))] <- 1
数据
df1 <- structure(list(Romance = c(0L, 1L, 0L, 1L), Horror = c(1L, 0L,
0L, 1L), Comedy = c(1L, 0L, 1L, 0L), Keyword = c("lol", "love",
"lol", "omg")), class = "data.frame", row.names = c(NA, -4L))
这是虚拟或一次性编码,因此您可以将 model.matrix
与因子(或字符)向量和没有截距的公式一起使用:
~ x + 0
~ x - 1
两者都可以。
dat <- read.table(header = TRUE, text = "Romance Horror Comedy Keyword
0 1 1 lol
1 0 0 love
0 0 1 lol
1 1 0 omg")
key <- c(Romance = 'love', Horror = 'omg', Comedy = 'lol')
tmp <- factor(dat$Keyword, key, names(key))
data.frame(model.matrix(~ tmp + 0))
# tmpRomance tmpHorror tmpComedy
# 1 0 0 1
# 2 1 0 0
# 3 0 0 1
# 4 0 1 0
由于 key
(因此因子的水平)与您的列具有相同的顺序,您也可以直接替换列:
dat[, 1:3] <- model.matrix(~ tmp + 0)
dat
# Romance Horror Comedy Keyword
# 1 0 0 1 lol
# 2 1 0 0 love
# 3 0 0 1 lol
# 4 0 1 0 omg
编辑
要将多个单词映射到一个类型,您可以使用一个列表作为您的键:
keywords <- c('lol', 'freak', 'kiss', 'ring', 'unknown', 'omg')
key <- list(
Romance = c('love', "kiss", "ring"),
Horror = c('omg', "freak", "kill"),
Comedy = 'lol'
)
lst <- stack(key)
tmp <- lst$ind[match(keywords, lst$values)]
data.frame(model.matrix(~ tmp + 0))
# tmpRomance tmpHorror tmpComedy
# 1 0 0 1
# 2 0 1 0
# 3 1 0 0
# 4 1 0 0
# 6 0 1 0
请注意,以上内容与列表中缺少的关键字不匹配(缺少第 5 行),因此为这些设置一个单独的类别也会很有用:
key <- c(key, Other = setdiff(keywords, unlist(key)))
lst <- stack(key)
tmp <- lst$ind[match(keywords, lst$values)]
data.frame(model.matrix(~ tmp + 0), keywords)
# tmpRomance tmpHorror tmpComedy tmpOther keywords
# 1 0 0 1 0 lol
# 2 0 1 0 0 freak
# 3 1 0 0 0 kiss
# 4 1 0 0 0 ring
# 5 0 0 0 1 unknown
# 6 0 1 0 0 omg
现在第 5 行显示正确
edit2
我刚刚了解到 R >= 3.5.0 最终 允许重复的标签,所以而不是做
key <- c(key, Other = setdiff(keywords, unlist(key)))
lst <- stack(key)
lst$ind[match(keywords, lst$values)]
# [1] Comedy Horror Romance Romance Other Horror
# Levels: Romance Horror Comedy Other
你可以简单地做
factor(keywords, unlist(key), rep(names(key), lengths(key)))
# [1] Comedy Horror Romance Romance Other Horror
# Levels: Romance Horror Comedy Other
Romance Horror Comedy Keyword
0 1 1 lol
1 0 0 love
0 0 1 lol
1 1 0 omg
大家好,我有一个像上面这样的数据集,我会用R来工作。我想要的是这样的:
如果keyword="lol",则喜剧=1,其他=0
如果关键字=“omg”,则恐怖=1,其他=0
If keyword= "love", make Romance=1, others=0
实际上,我试过 ifelse 语句,但没有用。顺便提一下,我有大约 200 个案例和 6 个变量。暂时谢谢了。
将前三列的列值更改为 1
df1[1:3] <- 0
然后,创建一个命名向量以匹配列名
nm1 <- setNames(c("Comedy", "Romance", "Horror"), c("lol", "love", "omg"))
根据'Keyword'的替换值,使用向量match
'df1'的列名得到列索引,cbind
用行索引,使用 row/column 索引的矩阵将数据集中的那些元素分配给 1
df1[1:3][cbind(seq_len(nrow(df1)), match(nm1[df1$Keyword], names(df1)))] <- 1
数据
df1 <- structure(list(Romance = c(0L, 1L, 0L, 1L), Horror = c(1L, 0L,
0L, 1L), Comedy = c(1L, 0L, 1L, 0L), Keyword = c("lol", "love",
"lol", "omg")), class = "data.frame", row.names = c(NA, -4L))
这是虚拟或一次性编码,因此您可以将 model.matrix
与因子(或字符)向量和没有截距的公式一起使用:
~ x + 0
~ x - 1
两者都可以。
dat <- read.table(header = TRUE, text = "Romance Horror Comedy Keyword
0 1 1 lol
1 0 0 love
0 0 1 lol
1 1 0 omg")
key <- c(Romance = 'love', Horror = 'omg', Comedy = 'lol')
tmp <- factor(dat$Keyword, key, names(key))
data.frame(model.matrix(~ tmp + 0))
# tmpRomance tmpHorror tmpComedy
# 1 0 0 1
# 2 1 0 0
# 3 0 0 1
# 4 0 1 0
由于 key
(因此因子的水平)与您的列具有相同的顺序,您也可以直接替换列:
dat[, 1:3] <- model.matrix(~ tmp + 0)
dat
# Romance Horror Comedy Keyword
# 1 0 0 1 lol
# 2 1 0 0 love
# 3 0 0 1 lol
# 4 0 1 0 omg
编辑
要将多个单词映射到一个类型,您可以使用一个列表作为您的键:
keywords <- c('lol', 'freak', 'kiss', 'ring', 'unknown', 'omg')
key <- list(
Romance = c('love', "kiss", "ring"),
Horror = c('omg', "freak", "kill"),
Comedy = 'lol'
)
lst <- stack(key)
tmp <- lst$ind[match(keywords, lst$values)]
data.frame(model.matrix(~ tmp + 0))
# tmpRomance tmpHorror tmpComedy
# 1 0 0 1
# 2 0 1 0
# 3 1 0 0
# 4 1 0 0
# 6 0 1 0
请注意,以上内容与列表中缺少的关键字不匹配(缺少第 5 行),因此为这些设置一个单独的类别也会很有用:
key <- c(key, Other = setdiff(keywords, unlist(key)))
lst <- stack(key)
tmp <- lst$ind[match(keywords, lst$values)]
data.frame(model.matrix(~ tmp + 0), keywords)
# tmpRomance tmpHorror tmpComedy tmpOther keywords
# 1 0 0 1 0 lol
# 2 0 1 0 0 freak
# 3 1 0 0 0 kiss
# 4 1 0 0 0 ring
# 5 0 0 0 1 unknown
# 6 0 1 0 0 omg
现在第 5 行显示正确
edit2
我刚刚了解到 R >= 3.5.0 最终 允许重复的标签,所以而不是做
key <- c(key, Other = setdiff(keywords, unlist(key)))
lst <- stack(key)
lst$ind[match(keywords, lst$values)]
# [1] Comedy Horror Romance Romance Other Horror
# Levels: Romance Horror Comedy Other
你可以简单地做
factor(keywords, unlist(key), rep(names(key), lengths(key)))
# [1] Comedy Horror Romance Romance Other Horror
# Levels: Romance Horror Comedy Other