如何在for循环中引用变量?

时间:2018-03-16 01:08:06

标签: r for-loop dplyr data.table

我循环遍历不同的data.tables和data.table中的变量。但是我在引用for循环

中的变量时遇到了麻烦
dt1 <- data.table(a1 = c(1,2,3), a2 = c(4,5,2))
dt2 <- data.table(a1 = c(1,43,1), a2 = c(52,4,1))

对于每个数据表,我想找到每个变量的平均值,用于观察变量!= 1.以下是我的尝试不起作用:

dtname = 'dt'
ind  = c('1', '2')
for (d in ind) {
  df <- get(paste0('dt', d, sep=''))
  for (v in ind) {
    varname <- paste0('a', v, sep='')
    df1 <- df %>%
      filter(varname!=1) %>%
      summarise(varname = mean(varname))
    print(df1)
    }
   }

所需的输出是在dt1中取a1 = c(2,3)的平均值,dt1中a2 =(4,5,2)的平均值,a1 = c(43)的平均值dt2,dt2中a2 = c(54,4)的平均值。

我在这里做错了什么?一般来说,我应该如何通过使用循环索引(v)和其他东西来引用拼凑在一起的for循环(varname)中的变量?

4 个答案:

答案 0 :(得分:3)

对于纯data.table方式,我会合并不同的data.tables并计算平均值:

# Concatenate the data.tables: 
all_dt <- rbind("dt1" = dt1, "dt2" = dt2, idcol = "origin")
all_dt
#    origin a1 a2
# 1:    dt1  1  4
# 2:    dt1  2  5
# 3:    dt1  3  2
# 4:    dt2  1 52
# 5:    dt2 43  4
# 6:    dt2  1  1

# Melt so that "a1" and "a2" are labels in a group column:
all_dt <- melt(all_dt, id.vars="origin")
all_dt
#     origin variable value
#  1:    dt1       a1     1
#  2:    dt1       a1     2
#  3:    dt1       a1     3
#  4:    dt2       a1     1
#  5:    dt2       a1    43
#  6:    dt2       a1     1
#  7:    dt1       a2     4
#  8:    dt1       a2     5
#  9:    dt1       a2     2
# 10:    dt2       a2    52
# 11:    dt2       a2     4
# 12:    dt2       a2     1

# Compute averages by each data.table and column group, ignoring 1s:
all_dt[value != 1, .(mean = mean(value)), by = .(origin, variable)]
#    origin variable      mean
# 1:    dt1       a1  2.500000
# 2:    dt2       a1 43.000000
# 3:    dt1       a2  3.666667
# 4:    dt2       a2 28.000000

答案 1 :(得分:1)

我根据@Amar和@Scott Richie的评论找到了解决方案

for (d in ind) {
  df <- get(paste0('dt', d, sep=''))
  for (v in ind) {
    varname <- paste0('a', v, sep='')
    df1 <- df[eval(as.name(varname))!=1, .(mean = 
                                 mean(eval(as.name(varname))))]
    print(df1)

   }
 }

谢谢大家!

答案 2 :(得分:0)

会采用矢量化方法。你正在使用R!

一种可能的方式:

require(dplyr)

dt1[dt1==1] <- NA #replace 1 with NA

dt1 %>% summarise_all(mean, na.rm = TRUE) #mean of all columns. 

   a1       a2
1 2.5 3.666667

答案 3 :(得分:0)

目前还不是很清楚你要做什么,但是如果你想用前面数据框的列的平均值替换数据框中的所有行,我建议使用数据框类型代替因为它更容易索引。这是应该工作的代码:

dt1 <- data.frame(a1 = c(1,2,3), a2 = c(4,5,2))
dt2 <- data.frame(a1 = c(1,43,1), a2 = c(52,4,1))

dtname = 'dt'
ind  = c('1', '2')
for (d in ind){
  df <- get(paste0('dt', d, sep=''))
  for (i in 1:nrow(df)){
    for (j in 1:ncol(df)){
      if (df[i,j] !=1){
        df[,j]<- mean(df[,j])
      }
     }
    print(df)
  }
}

之前代码无效的原因是因为变量被视为字符串而不是实际变量。您可以通过打印差异的数据类型来看到这一点:

dtname = 'dt'
ind  = c('1', '2')
for (d in ind) {
  df <- get(paste0('dt', d, sep=''))
  for (v in ind) {
    varname <- paste0('a', v, sep='')
    print(class(varname))
  }
}

只返回&#34;字符&#34;

使用变量名和数据框类型的另一种解决方案是将df索引如下:

df[["varname"]]


以下是此类操作的两个有用链接:
* link 1: How to find the mean of a column
* link 2: Data frames