我有一个复杂的问题,我将通过简化数据集来尝试简化。假设我有5个变量:
df$Id <- c(1:12)
df$Date <- c(NA,NA,a,a,b,NA,NA,b,c,c,b,a)
df$va <- c(1.1, 1.4, 2.5, ...) #12 randoms values
df$vb <- c(5.9, 2.3, 4.7, ...) #12 other random values
df$vc <- c(3.0, 3.3, 3.7, ...) #12 more random values
然后我想创建一个新变量,如果日期等于a,b或c,则从va,vb或vc获取值。我曾尝试过嵌套的if-else,但是没有用。我也尝试过:
df$new[df$date=='a' & !is.na(df$date)] <- df$va
df$new[df$date=='b' & !is.na(df$date)] <- df$vb
df$new[df$date=='c' & !is.na(df$date)] <- df$vc
这正确地将NA保留在新变量中,其中Date = NA,但是提供的值不是来自va,vb或vc,而是来自其他一些值。如果日期是&#39; a&#39;如果日期是&#39; b&#39;如果日期是&#39; c&#39,我如何得到df $ new等于va ;
答案 0 :(得分:5)
尝试
library(dplyr)
df %>%
mutate(new = (Date=="a")*va + (Date=="b")*vb + (Date=="c")*vc)
# Id Date va vb vc new
#1 1 <NA> 0.26550866 0.6870228 0.26722067 NA
#2 2 <NA> 0.37212390 0.3841037 0.38611409 NA
#3 3 a 0.57285336 0.7698414 0.01339033 0.5728534
#4 4 a 0.90820779 0.4976992 0.38238796 0.9082078
#5 5 b 0.20168193 0.7176185 0.86969085 0.7176185
#6 6 <NA> 0.89838968 0.9919061 0.34034900 NA
#7 7 <NA> 0.94467527 0.3800352 0.48208012 NA
#8 8 b 0.66079779 0.7774452 0.59956583 0.7774452
#9 9 c 0.62911404 0.9347052 0.49354131 0.4935413
#10 10 c 0.06178627 0.2121425 0.18621760 0.1862176
#11 11 b 0.20597457 0.6516738 0.82737332 0.6516738
#12 12 a 0.17655675 0.1255551 0.66846674 0.1765568
或者,
library(data.table)
setDT(df)[,new:= (Date=="a")*va + (Date=="b")*vb + (Date=="c")*vc,]
数据
set.seed(1)
df <- data.frame(Id = 1:12,
Date = c(NA,NA,"a","a","b",NA,NA,"b","c","c","b","a"),
va = runif(12),
vb = runif(12),
vc = runif(12), stringsAsFactors = FALSE)
答案 1 :(得分:1)
您也可以使用row/column
进行base R
索引(使用@ExperimenteR中的数据)。即使有unique
&#39;日期&#39;与相应的&#39; v&#39;列,我们可能不需要更改代码,尤其是cbind(..)
部分。
df$new <- df[-(1:2)][cbind(1:nrow(df),match(df$Date, sort(unique(df$Date))))]
df
# Id Date va vb vc new
#1 1 <NA> 0.26550866 0.6870228 0.26722067 NA
#2 2 <NA> 0.37212390 0.3841037 0.38611409 NA
#3 3 a 0.57285336 0.7698414 0.01339033 0.5728534
#4 4 a 0.90820779 0.4976992 0.38238796 0.9082078
#5 5 b 0.20168193 0.7176185 0.86969085 0.7176185
#6 6 <NA> 0.89838968 0.9919061 0.34034900 NA
#7 7 <NA> 0.94467527 0.3800352 0.48208012 NA
#8 8 b 0.66079779 0.7774452 0.59956583 0.7774452
#9 9 c 0.62911404 0.9347052 0.49354131 0.4935413
#10 10 c 0.06178627 0.2121425 0.18621760 0.1862176
#11 11 b 0.20597457 0.6516738 0.82737332 0.6516738
#12 12 a 0.17655675 0.1255551 0.66846674 0.1765568
答案 2 :(得分:0)
我被告知我的代码问题是我需要在任何一方放置索引。如果没有右侧的索引,则不知道应用该值的行。所以在这种情况下正确的代码是:
df$new[df$date %in% 'a' & !is.na(df$date)] <- df$va[df$date %in% 'a' & !is.na(df$date)]
df$new[df$date %in% 'b' & !is.na(df$date)] <- df$vb[df$date %in% 'b' & !is.na(df$date)]
df$new[df$date %in% 'c' & !is.na(df$date)] <- df$vc[df$date %in% 'c' & !is.na(df$date)]
或者,另一位用户注意到有一种方法可以使用ifelse,这可以在这里被视为正确的答案:https://stats.stackexchange.com/questions/151345/how-to-create-a-new-variable-with-values-from-different-variables-if-another-var
当我在该链接中添加回答时,我发现更好的方法是将%替换为%=%,以便创建一个数字变量而不是一个列表,其中包含36121个观察值的每一个我的数据集(我提供的示例中有12个)。那看起来像是:
$_POST