如何编写一个简单的 for 循环,使用键值对根据旧列中的值填充新列?
Posted
技术标签:
【中文标题】如何编写一个简单的 for 循环,使用键值对根据旧列中的值填充新列?【英文标题】:How to write a simple for loop that will populate a new column based on values in an old column, using key-value pairs? 【发布时间】:2022-01-17 11:44:44 【问题描述】:我正在处理如下所示的数据:
label |
---|
a |
b |
c |
我已经创建了一个键值索引(使用下面的代码),用于基于现有列创建新列。
values <- c("word1", "word2", "word3")
keys <- c("a", "b", "c")
index <- setNames(as.list(values), keys)
有了这个索引,我希望能够用一个简单的单行 for 循环创建一个新列,如下所示。
df$newcol <- for (x in df$label)index$x
不过,这段代码似乎根本不会在我的数据框中产生任何变化。我在这里不明白什么?
【问题讨论】:
【参考方案1】:尝试检查for (x in df$label)print(index$x)
。
它会返回
NULL
NULL
NULL
不要在函数内部使用$
,而是尝试使用[]
来调用一些值。
而且,先创建一个新向量,然后将其附加到 df$newcol
即可。
newcol <- c()
for (x in df$label)
newcol <- c(newcol, index[x])
df$newcol <- newcol
df
label newcol
1 a word1
2 b word2
3 c word3
或者,对for
循环稍作改动
for (x in 1:nrow(df))
df$newcol[x] <- index[df$label[x]]
df
label newcol
1 a word1
2 b word2
3 c word3
【讨论】:
【参考方案2】:我会使用dplyr::recode
:
df$newcol <- dplyr::recode(df$label, !!!index)
输出:
> df
label newcol
1 a word1
2 b word2
3 c word3
>
【讨论】:
喜欢 tidyverse 解决方案,谢谢!如果可能的话,你能解释一下 !!!index 背后的逻辑是什么吗? @nlplearner!!!
将值解压缩到单独的参数中,而 recode
需要第一个序列,然后是多个值用于映射,例如 dplyr::recode(x, value1, value2, ... , value100)
,所以如果我不使用!!!
,它将被视为dplyr::recode(x, values)
。它将第二个向量视为一个值,这里是这个函数的官方文档:rdocumentation.org/packages/dplyr/versions/0.7.8/topics/recode
@nlplearner 更多关于三个感叹号的信息:Triple exclamation marks on R【参考方案3】:
您可能希望使用数据框而不是列表索引。然后使用match()
。
index <- data.frame(values, keys)
df$newcol <- index[match(df$label, index$keys), 'values']
df
# label newcol
# 1 a word1
# 2 b word2
# 3 c word3
# 4 a word1
# 5 b word2
# 6 c word3
数据:
df <- data.frame(label=letters[c(1:3, 1:3)])
index <- structure(list(values = c("word1", "word2", "word3"), keys = c("a",
"b", "c")), class = "data.frame", row.names = c(NA, -3L))
【讨论】:
以上是关于如何编写一个简单的 for 循环,使用键值对根据旧列中的值填充新列?的主要内容,如果未能解决你的问题,请参考以下文章
我可以在 for 循环中将键值对添加到 NSarray 或字典吗?