【问题标题】:How to add a column to a dataframe in R? [duplicate]如何在R中的数据框中添加一列? [复制]
【发布时间】:2021-12-20 20:37:25
【问题描述】:

我正在处理 ToothGrowth 数据:

library(datasets)
data(ToothGrowth)

这里我有三列,长度、补充和剂量。我想添加第四列,其中包含取决于剂量量的分类变量,例如,如果剂量 = 0.5,则为“D5”,如果剂量 = 1,则为“D1”,我尝试了以下操作:

data(ToothGrowth)
df_TD <- ToothGrowth
dosiscatg <- NULL
for(i in 1:nrow(df_TD)) {
  if df_TD$dose==0.5 {
    dosiscatg <- c(dosiscatg, "D0.5")
  } else if df_TD$dose==1 {
    dosiscatg <- c(dosiscatg, "D1")
  } else if df_TD$dose==2 {
    dosiscatg <- c(dosiscatg, "D2")
  }
}

但我一直收到括号“{}”的错误,我也不知道该代码是否正确。

【问题讨论】:

  • 这样的事情应该在向量上作为一个整体而不是在for循环中完成,任何推荐其他任何东西的教程要么有另一个动机(一般教授编程或展示“低效的 R是”,不是真的)或作为“R 中的良好实践”的可信度较低。您可以使用df_TD$newcol &lt;- cut(ToothGrowth$dose, c(0, 0.9, 1.5, 3), labels = c("D5", "D1", "D2")) 之类的东西;这是一个因素,所以如果你想要一个文字字符串,请用 as.character(.) 包装它。

标签: r dataframe loops


【解决方案1】:

试试这个:

data(ToothGrowth)
df_TD <- ToothGrowth
dosiscatg <- NULL
for(i in 1:nrow(df_TD)) {
  if df_TD$dose[i]==0.5 {
    dosiscatg <- c(dosiscatg, "D0.5")
  } else if df_TD$dose[i]==1 {
    dosiscatg <- c(dosiscatg, "D1")
  } else if df_TD$dose[i]==2 {
    dosiscatg <- c(dosiscatg, "D2")
  }
}

编辑:正如人们指出的那样,这只是纠正代码的语法问题,但不鼓励一起解决

【讨论】:

  • 恕我直言,正如@r2evans 在他的评论中所说,不应该鼓励使用 for 循环来处理这类事情,即使这是 OP 要求的。如果合适的话,一定要正确的 OPs 语法,但我觉得 complete 答案将包括适当的矢量化代码以及为什么它更好的解释。基准测试将完成答案。
  • 谢谢,下次我会记住的!
【解决方案2】:

这是使用mutate 和cut 的另一个选项:

library(dplyr)    
df_TD %>%  
  dplyr::mutate(dosiscatg = cut(dose, breaks = c(0, 0.5, 1.0,2.0), labels = c("D0.5", "D1", "D2")))
    len supp dose dosiscatg
1   4.2   VC  0.5      D0.5
2  11.5   VC  0.5      D0.5
3   7.3   VC  0.5      D0.5
4   5.8   VC  0.5      D0.5
5   6.4   VC  0.5      D0.5
6  10.0   VC  0.5      D0.5
7  11.2   VC  0.5      D0.5
8  11.2   VC  0.5      D0.5
9   5.2   VC  0.5      D0.5
10  7.0   VC  0.5      D0.5
11 16.5   VC  1.0        D1
12 16.5   VC  1.0        D1
13 15.2   VC  1.0        D1
14 17.3   VC  1.0        D1
15 22.5   VC  1.0        D1
16 17.3   VC  1.0        D1
17 13.6   VC  1.0        D1
18 14.5   VC  1.0        D1
19 18.8   VC  1.0        D1
20 15.5   VC  1.0        D1
21 23.6   VC  2.0        D2
22 18.5   VC  2.0        D2
23 33.9   VC  2.0        D2
24 25.5   VC  2.0        D2
25 26.4   VC  2.0        D2
26 32.5   VC  2.0        D2
27 26.7   VC  2.0        D2
28 21.5   VC  2.0        D2
29 23.3   VC  2.0        D2
30 29.5   VC  2.0        D2
31 15.2   OJ  0.5      D0.5
32 21.5   OJ  0.5      D0.5
33 17.6   OJ  0.5      D0.5
34  9.7   OJ  0.5      D0.5
35 14.5   OJ  0.5      D0.5
36 10.0   OJ  0.5      D0.5
37  8.2   OJ  0.5      D0.5
38  9.4   OJ  0.5      D0.5
39 16.5   OJ  0.5      D0.5
40  9.7   OJ  0.5      D0.5
41 19.7   OJ  1.0        D1
42 23.3   OJ  1.0        D1
43 23.6   OJ  1.0        D1
44 26.4   OJ  1.0        D1
45 20.0   OJ  1.0        D1
46 25.2   OJ  1.0        D1
47 25.8   OJ  1.0        D1
48 21.2   OJ  1.0        D1
49 14.5   OJ  1.0        D1
50 27.3   OJ  1.0        D1
51 25.5   OJ  2.0        D2
52 26.4   OJ  2.0        D2
53 22.4   OJ  2.0        D2
54 24.5   OJ  2.0        D2
55 24.8   OJ  2.0        D2
56 30.9   OJ  2.0        D2
57 26.4   OJ  2.0        D2
58 27.3   OJ  2.0        D2
59 29.4   OJ  2.0        D2
60 23.0   OJ  2.0        D2

【讨论】:

    【解决方案3】:

    使用 dplyr:

    library(dplyr)
    
    df_TD <- df_TD %>%
      mutate(dosiscatg = case_when(
        dose==0.5 ~ 'D0.5',
        dose==1   ~ 'D1',
        dose==2   ~ 'D2',
        TRUE ~ NA_character_
      ))
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 2021-12-16
    • 2019-04-22
    • 2017-08-05
    • 1970-01-01
    • 2021-10-16
    • 2019-09-09
    相关资源
    最近更新 更多