【问题标题】:create new column by adding two columns in r within for loop [duplicate]通过在for循环中的r中添加两列来创建新列[重复]
【发布时间】:2015-08-13 11:25:24
【问题描述】:

假设我有示例数据框 (df):

id col1 col2 col3 col4 col5 col6
 1   2    3    2    6    2    8
 2   3    2    4    1    3    2 
 3   4    2    9    7    8    7 
 4   7    6    3    2    9    2

现在我尝试一次添加 2 列并创建新列,即 col1+col2、col3+col4、col5+col6

期望的输出:

id col1 col2 col3 col4 col5 col6 t_1 t_3 t_5
 1   2    3    2    6    2    8    5   8   10
 2   3    2    4    1    3    2    5   5   5
 3   4    2    9    7    8    7    6   16  15
 4   7    6    3    2    9    2    13  5   11

我写了以下代码:

for(i in c(1, 3, 5)){
paste('df$t', i, sep= '_') <- as.numeric(df[, i]) + as.numeric(df[, i+1])
}

但我收到以下错误:

粘贴错误("df$t", i, sep = "_")

我在这里做错了吗?

【问题讨论】:

  • 您做错的是paste('df$t', i, sep= '_') 返回长度为一的字符向量 "df$t_i",而不是对象 df$t_i。例如,您可以使用assign 以编程方式分配变量

标签: r for-loop dataframe


【解决方案1】:

根据预期的输出,我们可以对没有第一个 'id' 列的 'df1' 的交替列进行子集化,我们 + 那些具有相似维度的数据集,并根据该输出在原始数据集中创建新列。

df1[paste('t', c(1,3,5), sep="_")] <-  df1[-1][c(TRUE, FALSE)]+
                              df1[-1][c(FALSE, TRUE)]
df1
#   id col1 col2 col3 col4 col5 col6 t_1 t_3 t_5
#1  1    2    3    2    6    2    8   5   8  10
#2  2    3    2    4    1    3    2   5   5   5
#3  3    4    2    9    7    8    7   6  16  15
#4  4    7    6    3    2    9    2  13   5  11

为了清楚起见,第一步是删除第一列 df1[-1],然后我们使用逻辑向量 (c[TRUE, FALSE)]) 对每个交替列进行子集化。这将被回收到数据集的长度。

df1[-1][c(TRUE, FALSE)]
#  col1 col3 col5
#1    2    2    2
#2    3    4    3
#3    4    9    8
#4    7    3    9

同样,我们对下一个交替的列进行子集化。

df1[-1][c(FALSE, TRUE)]
#  col2 col4 col6
#1    3    6    8
#2    2    1    2
#3    2    7    7
#4    6    2    2

两个子集数据集具有相同的维度,因此我们只需 + 即可获取对应元素的 + 输出列

 df1[-1][c(TRUE, FALSE)]+df1[-1][c(FALSE, TRUE)]
 #  col1 col3 col5
 #1    5    8   10
 #2    5    5    5
 #3    6   16   15
 #4   13    5   11

数据

df1 <- structure(list(id = 1:4, col1 = c(2L, 3L, 4L, 7L), col2 = c(3L, 
2L, 2L, 6L), col3 = c(2L, 4L, 9L, 3L), col4 = c(6L, 1L, 7L, 2L
), col5 = c(2L, 3L, 8L, 9L), col6 = c(8L, 2L, 7L, 2L)), .Names = c("id", 
"col1", "col2", "col3", "col4", "col5", "col6"), class = "data.frame",
row.names = c(NA, -4L))

【讨论】:

  • 如果你能解释你做了什么,那就太好了,我不明白 df1[-1] 做了什么,但无法得到全部。也可以使用for循环吗?
  • @DheerajSingh 更新了一些解释。希望对你有帮助
【解决方案2】:

这样就可以了……

df$t_1 <- df$col1 + df$col2
df$t_3 <- df$col3 + df$col4
df$t_5 <- df$col5 + df$col6

您不需要运行循环。

【讨论】:

  • 这不是一个好方法,因为我必须对大量列应用此操作。
【解决方案3】:

我认为值得一提的是 Tyler Rinker 在此 post 中针对此问题所做的其他方法。我们创建一个列对列表,稍后将其传递给 lappy。最后,我们结合原始数据框(df1)和矩阵(df2)。

n <- ncol(df1)
ind <- split(2:n, rep(2:n, each = 2, length = n - 1))
df2 <- do.call(cbind, lapply(ind, function(i) rowSums(df1[, i])))
cbind(df1, df2

输出:

  id col1 col2 col3 col4 col5 col6  2  3  4
1  1    2    3    2    6    2    8  5  8 10
2  2    3    2    4    1    3    2  5  5  5
3  3    4    2    9    7    8    7  6 16 15
4  4    7    6    3    2    9    2 13  5 11

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多