我有一个数据框,我想添加一列。为此,我使用dplyr :: mutate。但是,我要添加的列的值取决于其他列的值。我使用case_when()并解决了问题,但是如果有很多情况,代码不适合编写(下面显示一个示例),所以我想知道是否还有另一个选择(可能是循环)来简化此操作。
以下代码有效:
NewTable <- Table %>%
dplyr::mutate(ColumnB = case_when(
ColumnA=="2000" ~ 0,
ColumnA=="2001" ~ 4,
ColumnA=="2002" ~ 8,
ColumnA=="2003" ~ 12,
ColumnA=="2004" ~ 16,
ColumnA=="2005" ~ 20,
ColumnA=="2006" ~ 24,
ColumnA=="2007" ~ 28,
ColumnA=="2008" ~ 32,
ColumnA=="2009" ~ 36,
ColumnA=="2010" ~ 40,
ColumnA=="2011" ~ 44))
我该如何改善?非常感谢。
答案 0 :(得分:1)
由于您更改了数据,因此您可能需要尝试以下操作:
Table<-data.frame(A = c("2000", "2001", "2002", "2003", "2004"))
Table$B = (as.numeric(as.character(Table$A))-2000)*4
如果没有这种模式,则可以生成具有匹配的A和B的值的列表,然后将它们合并:
match_list<-data.frame(A = c("2000", "2001", "2002", "2003", "2004"),
B = c(0, 4, 8, 16, 20))
merge(Table, match_list, by = "A") # Table itself does not have B at this stage
这只能保存一些键入内容。
答案 1 :(得分:0)
这就是我要做的:
lkp <- setNames(c(0, 4, 8, 16, 20),
c("2000", "2001", "2002", "2003", "2004"))
df <- data.frame(ColumnA = c("2004","2002"),stringsAsFactors = FALSE)
dplyr::mutate(df, ColumnB = lkp[ColumnA])
#> ColumnA ColumnB
#> 1 2004 20
#> 2 2002 8
由reprex package(v0.3.0)于2019-11-06创建
答案 2 :(得分:0)
由于您正在编写B列,因此我认为Table中不存在该列,因此联接可以解决问题。
library(dplyr)
NewTable <- left_join( Table,
tibble( A = c("2000", "2001", "2002", "2003", "2004"),
B = seq(from = 0, to = 32, by = 4) )
答案 3 :(得分:0)
这是一个使用mapvalues
软件包中的plyr
的解决方案。我经常使用。
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
# Create a simulated data frame
set.seed(9049)
Table <- data.frame(columnA = as.character(sample(2000:2011,
size = 100,
replace = TRUE)),
stringsAsFactors = FALSE)
# Extract unique levels from column A
colA_levels <- unique(Table$columnA)
# Create unique levels of column B to map to
colB_levels <- (as.numeric(colA_levels) - 2000) * 4
# Use `mapvalues` from `plyr` package
#
NewTable <- Table %>%
mutate(columnB = plyr::mapvalues(columnA,
from = colA_levels,
to = colB_levels))
head(NewTable, 10)
#> columnA columnB
#> 1 2008 32
#> 2 2011 44
#> 3 2007 28
#> 4 2011 44
#> 5 2001 4
#> 6 2010 40
#> 7 2000 0
#> 8 2007 28
#> 9 2000 0
#> 10 2002 8
由reprex package(v0.3.0)于2019-11-06创建
答案 4 :(得分:-1)
考虑到OP的注释,您可以编写一个函数(概率为this answer):
library(tidyverse)
letter2num <- function(x) {(utf8ToInt(x) - utf8ToInt("a")) * 2}
tibble(x = letters) %>%
rowwise() %>%
mutate(y = letter2num(x))