繁体   English   中英

R:遍历列名

[英]R: looping through column names

我是Stata用户,尝试切换到R并进行常规的初学者奋斗。 我一直在尝试(但失败)做循环几天,现在我投降了。 我想做的事情(循环):

  • 从变量名列表开始

  • 创建一个新变量

  • 根据现有变量的值重新编码该新变量

  • 可能使用dplyr语法这样做,但这不是必需的,只是为了与我的其余代码保持一致。

这是我尝试做的一个程式化示例。 在我的实际数据中,xx和xy变量源自应用于2个现有数据帧的join函数。

N <- 1000
  df  <- data.frame(x1 = rnorm(N),
x2.x = rnorm(N)+2,x2.y = rnorm(N)-2,
x3.x = rnorm(N)+3,x3.y = rnorm(N)-3)

varlist <- c("x2","x3")
lapply(varlist, function(x) {
   df <- df %>% mutate(x = ifelse(x1 < 0, paste0(x,".y"),paste0(x,".x")) # generate varialble "x" values from existing x.x and x.y
  })

当我运行代码的lapply部分时,我收到错误消息

错误:“:df <-df%>%mutate(x = ifelse(x1 <0,paste0(x,”。y“),paste0(x,”。x“))#生成变量x“来自现有xx和xy的值}”

即使可以预料到...我确信代码中存在许多错误,部分原因是因为我习惯于Stata中的宏,而R中没有直接等效的宏。无论如何,如果您能指出我的意思,正确的方向太棒了!

您的代码无法正常工作的原因是您的paste0(x, ".y")实际上是使用.y粘贴x 就是这样,您不是要告诉它按该列对数据进行子集化。

您实际上应该做的是根据paste0(x, ".y")生成的列名对数据进行子集设置。 因此,例如,要获取数据x2.y的列,您可以

df[, paste0(varlist[1], ".y")]
## and of course the same can be done for second item of varlist
# df[, paste0(varlist[2], ".y")]

现在我们知道了如何通过变量名对列进行子集化,并且因为您想学习如何在循环中编写列,我们可以将varlist[1] (和varlist[2] )中的数字替换为“ looping”变量

这有两种方法,一种使用for循环,另一种使用sapply

对于循环

for(i in varlist){
  df[, i] <- ifelse(df[, "x1"] < 0, df[, paste0(i, ".y")], df[, paste0(i, ".x")])
}

head(df)
#            x1       x2.x       x2.y     x3.x       x3.y         x2        x3
# 1 -0.56047565  1.0042013 -2.5116037 2.849693 -2.8034502 -2.5116037 -2.803450
# 2 -0.23017749  0.9600450 -1.7630621 2.672243 -2.3498868 -1.7630621 -2.349887
# 3  1.55870831  1.9820198 -2.5415892 1.551835 -2.3289958  1.9820198  1.551835
# 4  0.07050839  1.8678249 -0.7807724 2.302715 -4.2841578  1.8678249  2.302715
# 5  0.12928774 -0.5493428 -1.8258641 5.598490 -5.0261096 -0.5493428  5.598490
# 6  1.71506499  3.0405735 -2.6152683 2.962585 -0.7946739  3.0405735  2.962585

贴上

您也可以使用*apply来执行此操作,在这种情况下,我使用sapply ,以使其“简化”结果(而lapply会返回列表)

df[, varlist] <- sapply(varlist, function(x){
   ifelse(df[, "x1"] < 0, df[, paste0(x, ".y")], df[, paste0(x, ".x")])
})

head(df)
#            x1       x2.x       x2.y     x3.x       x3.y         x2        x3
# 1 -0.56047565  1.0042013 -2.5116037 2.849693 -2.8034502 -2.5116037 -2.803450
# 2 -0.23017749  0.9600450 -1.7630621 2.672243 -2.3498868 -1.7630621 -2.349887
# 3  1.55870831  1.9820198 -2.5415892 1.551835 -2.3289958  1.9820198  1.551835
# 4  0.07050839  1.8678249 -0.7807724 2.302715 -4.2841578  1.8678249  2.302715
# 5  0.12928774 -0.5493428 -1.8258641 5.598490 -5.0261096 -0.5493428  5.598490
# 6  1.71506499  3.0405735 -2.6152683 2.962585 -0.7946739  3.0405735  2.962585

数据

set.seed(123)   ## setting the seed as we're sampling
N <- 1000
df  <- data.frame(x1 = rnorm(N),
                  x2.x = rnorm(N)+2,x2.y = rnorm(N)-2,
                  x3.x = rnorm(N)+3,x3.y = rnorm(N)-3)

试试这个兄弟

mutate_替换mutate

https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html

这为我工作:

lapply(varlist, function(x) 
  df <- df %>% mutate(x = ifelse(x1 < 0, paste0(x,".y"),paste0(x,".x")) # generate varialble "x" values from existing x.x and x.y
))

您不需要大括号即可使用lapply指定循环。 阅读此内容以获得有关lapply语法的更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM