使用此df:
DF = data.frame(m=rep(1:2,2), y=rep(1998:1999,each=2), A=c(2:5), B=c(4,NA,6,7))
> DF
m y A B
1 1 1998 2 4
2 2 1998 3 NA
3 1 1999 4 6
4 2 1999 5 7
如何使用此值作为坐标替换单个单元格:
m = 2 ; y = 1999 ; col = 'A' ; val = 72
按照这些值,我想用72替换5。
修改 在测试所有答案时,我意识到我的问题非常基本,并不能代表我的问题。我试图在没有for循环的情况下这样做但失败并最终使用它。
所以,我想替换DF
数据框中的值,但使用其他数据框:
repl = data.frame(m=c(2,1), y=c(1999,1998), col=c('A','B'), val=c(72,100))
> repl
m y col val
1 2 1999 A 72
2 1 1998 B 100
这意味着repl
数据框的每一行都是DF
中要替换的值。
我一直在尝试为每一行使用Psidom回答mutate(A = replace(A, m == 2 & y == 1999, 72)
,但想知道是否可以在没有循环或没有使用列名的情况下完成。
谢谢。
答案 0 :(得分:2)
dplyr
方式为mutate
+ if_else
:
DF %>% mutate(A = if_else(m == 2 & y == 1999, 72L, A))
# m y A B
#1 1 1998 2 4
#2 2 1998 3 NA
#3 1 1999 4 6
#4 2 1999 72 7
或mutate
+ replace
:
DF %>% mutate(A = replace(A, m == 2 & y == 1999, 72))
# m y A B
#1 1 1998 2 4
#2 2 1998 3 NA
#3 1 1999 4 6
#4 2 1999 72 7
取决于条件,返回一个替换了预期值的新向量。
更新如果您需要同时进行多项更新,您可以:
1)重塑DF
,以便将要更新的列收集到一个列中;
2)加入两个条件列m
和y
以及列标题列;
3)更新值;
4)重新塑造数据帧;
与tidyr
一起,您可以这样做:
library(dplyr); library(tidyr)
DF %>%
gather(col, vals, -m, -y) %>%
left_join(repl, by = c("m", "y", "col")) %>%
mutate(vals = coalesce(val, vals)) %>%
select(-val) %>%
spread(col, vals)
# m y A B
#1 1 1998 2 100
#2 1 1999 4 6
#3 2 1998 3 NA
#4 2 1999 72 7
答案 1 :(得分:0)
对于你的后续问题,base-R中的单行方法将是
lapply(1:nrow(repl), function(i)
DF[DF$m==repl$m[i] & DF$y==repl$y[i], repl$col[i]] <<- repl$val[i])
DF
m y A B
1 1 1998 2 100
2 2 1998 3 NA
3 1 1999 4 6
4 2 1999 72 7
这会遍历repl
的每一行并对DF
进行更改。 <<-
强制它对全局环境中的原始DF
进行更改。