我在数据框中有一堆od列,其中两列是这样的
col1 | col2
-----| -------------
2 | M
3 | B
1 | m
5 | K
3 | k
我想要的是创建一个包含以下内容的新列:
如果col2中的值是k或K,则来自col1 * 10 ^ 3的值
如果col2中的值为M或m,则为col1 * 10 ^ 6,
col1 * 10 ^ 9如果col2中的值是B,
如果是其他的话,则为0。
我知道在有二元条件时如何做ifelse,但我不知道如何用这样的多个条件来做。感谢。
答案 0 :(得分:5)
您可以创建一个命名向量,并将其与“col2”列匹配以创建乘数。除M,m,K,k,B或b之外的所有值都会产生NA
,因此如果您想要“0”,则只需从新列中对NA
进行子集,然后将其替换为0手动。
Mults <- c(M = 10^6, m = 10^6, K = 10^3, k = 10^3, B = 10^9, b = 10^9)
Mults[mydf$col2]
# M B m K k <NA>
# 1e+06 1e+09 1e+06 1e+03 1e+03 NA
mydf$col3 <- mydf$col1 * Mults[mydf$col2]
mydf$col3[is.na(mydf$col3)] <- 0
mydf
# col1 col2 col3
# 1 2 M 2e+06
# 2 3 B 3e+09
# 3 1 m 1e+06
# 4 5 K 5e+03
# 5 3 k 3e+03
# 6 3 x 0e+00
这是我使用的“mydf”(带有一个额外的行):
mydf <- structure(list(col1 = c(2, 3, 1, 5, 3, 3), col2 = c("M", "B",
"m", "K", "k", "x"), col3 = c(2e+06, 3e+09, 1e+06, 5000, 3000, 0)),
.Names = c("col1", "col2", "col3"), row.names = c(NA, 6L),
class = "data.frame")
答案 1 :(得分:4)
switch
:
f <- function(multi, test)
multi * switch(tolower(test),
"m" = 10^6,
"k" = 10^3,
"b" = 10^9,
0
)
within(df, col3 <- mapply(f, col1, col2, SIMPLIFY=TRUE))
# col1 col2 col3
# 1 2 M 2e+06
# 2 3 B 3e+09
# 3 1 m 1e+06
# 4 5 K 5e+03
# 5 3 k 3e+03
答案 2 :(得分:2)
这根本不优雅,但你可以这样做。问题是,如果你有更多可能的案例,它会变得很烦人。
DB <- data.frame(col1=c(2,3,1,5,3), col2=c("M","B","m","K","k"))
DB$col3 <- NA
DB$col3 <- ifelse(DB$col2=="K" | DB$col2=="k", DB$col1 * (10^3), DB$col3)
DB$col3 <- ifelse(DB$col2=="M" | DB$col2=="m", DB$col1 * (10^6), DB$col3)
DB$col3 <- ifelse(DB$col2=="B", DB$col1 * (10^9), DB$col3)
DB$col3 <- ifelse(is.na(DB$col2)==TRUE, 0, DB$col3)
或者您也可以这样做
DB <- data.frame(col1=c(2,3,1,5,3), col2=c("M","B","m","K","k"))
DB2 <- data.frame(col2=c("M","B","m","K","k"), tmp=c(10^6,10^9,10^6,10^3, 10^3))
DB<- merge(DB, DB2, by="col2")
DB$col3 <- DB$col1 * DB$tmp
DB$tmp <- NULL
答案 3 :(得分:1)
以下是使用mapply
和mget
的另一种方式。
x <- with(mydf, list(K=col1*10^3, M=col1*10^6, B=col1*10^9, col2=toupper(col2)))
mydf$col3 <-
do.call(mapply, c(function(K,M,B,col2) unlist(mget(col2, ifnotfound=0)), x))
# col1 col2 col3
# 1 2 M 2e+06
# 2 3 B 3e+09
# 3 1 m 1e+06
# 4 5 K 5e+03
# 5 3 k 3e+03
# 6 3 x 0e+00