将列添加到data.frame

Sus*_*ker 106 r dataframe

我有下面的data.frame.我想添加一个列,根据第1列(h_no)分类我的数据,第一个系列的h_no 1,2,3,4是1级,第2个系列h_no(1到7)是2级等.如最后一栏中所示.

h_no  h_freq  h_freqsq
1     0.09091 0.008264628 1
2     0.00000 0.000000000 1
3     0.04545 0.002065702 1
4     0.00000 0.000000000 1  
1     0.13636 0.018594050 2
2     0.00000 0.000000000 2
3     0.00000 0.000000000 2
4     0.04545 0.002065702 2
5     0.31818 0.101238512 2
6     0.00000 0.000000000 2
7     0.50000 0.250000000 2 
1     0.13636 0.018594050 3 
2     0.09091 0.008264628 3
3     0.40909 0.167354628 3
4     0.04545 0.002065702 3
Run Code Online (Sandbox Code Playgroud)

Rom*_*rik 149

您可以使用各种技术向数据添加列.以下引用来自相关帮助文本的"详细信息"部分[[.data.frame.

数据帧可以以多种模式索引.当[[[单个向量索引(x[i]x[[i]])一起使用时,它们将数据框索引为就像它是一个列表一样.

my.dataframe["new.col"] <- a.vector
my.dataframe[["new.col"]] <- a.vector
Run Code Online (Sandbox Code Playgroud)

data.frame方法$,x作为列表处理

my.dataframe$new.col <- a.vector
Run Code Online (Sandbox Code Playgroud)

[[[两个索引(x[i, j]x[[i, j]])一起使用时,它们就像索引矩阵一样

my.dataframe[ , "new.col"] <- a.vector
Run Code Online (Sandbox Code Playgroud)

由于该方法data.frame假设如果您未指定是否使用列或行,则会假定您的意思是列.


对于您的示例,这应该工作:

# make some fake data
your.df <- data.frame(no = c(1:4, 1:7, 1:5), h_freq = runif(16), h_freqsq = runif(16))

# find where one appears and 
from <- which(your.df$no == 1)
to <- c((from-1)[-1], nrow(your.df)) # up to which point the sequence runs

# generate a sequence (len) and based on its length, repeat a consecutive number len times
get.seq <- mapply(from, to, 1:length(from), FUN = function(x, y, z) {
            len <- length(seq(from = x[1], to = y[1]))
            return(rep(z, times = len))
         })

# when we unlist, we get a vector
your.df$group <- unlist(get.seq)
# and append it to your original data.frame. since this is
# designating a group, it makes sense to make it a factor
your.df$group <- as.factor(your.df$group)


   no     h_freq   h_freqsq group
1   1 0.40998238 0.06463876     1
2   2 0.98086928 0.33093795     1
3   3 0.28908651 0.74077119     1
4   4 0.10476768 0.56784786     1
5   1 0.75478995 0.60479945     2
6   2 0.26974011 0.95231761     2
7   3 0.53676266 0.74370154     2
8   4 0.99784066 0.37499294     2
9   5 0.89771767 0.83467805     2
10  6 0.05363139 0.32066178     2
11  7 0.71741529 0.84572717     2
12  1 0.10654430 0.32917711     3
13  2 0.41971959 0.87155514     3
14  3 0.32432646 0.65789294     3
15  4 0.77896780 0.27599187     3
16  5 0.06100008 0.55399326     3
Run Code Online (Sandbox Code Playgroud)

  • @huon-dbaupp 带逗号的方法是明确的,也适用于矩阵,而最后一个仅适用于 data.frames。如果未提供逗号,R 假定您指的是列。 (2认同)

小智 10

很容易:您的数据框是A.

b <- A[,1]
b <- b==1
b <- cumsum(b)
Run Code Online (Sandbox Code Playgroud)

然后你得到专栏b.

  • @RomanLuštrik,这个解决方案可以在一行中很好地重写.使用你的`your.df`数据,你可以简单地做`your.df $ group = cumsum(your.df [,1] == 1)`来得到你的新组列. (2认同)

huo*_*uon 7

如果我正确理解了这个问题,你想要检测何时h_no不增加然后增加class.(我将逐步介绍如何解决这个问题,最后有一个独立的功能.)

工作

我们现在只关心h_no列,所以我们可以从数据框中提取它:

> h_no <- data$h_no
Run Code Online (Sandbox Code Playgroud)

我们想要检测何时h_no不上升,我们可以通过计算连续元素之间的差异为负或零来做.R提供的diff功能为我们提供了差异的载体:

> d.h_no <- diff(h_no)
> d.h_no
 [1]  1  1  1 -3  1  1  1  1  1  1 -6  1  1  1
Run Code Online (Sandbox Code Playgroud)

一旦我们有了这个,找到非正面的是一件简单的事情:

> nonpos <- d.h_no <= 0
> nonpos
 [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
[13] FALSE FALSE
Run Code Online (Sandbox Code Playgroud)

在R中,TRUE并且FALSE基本上与1和相同0,因此如果我们得到累积和nonpos,它将在(几乎)适当的点上增加1.该cumsum功能(基本上与之相反diff)可以做到这一点.

> cumsum(nonpos)
 [1] 0 0 0 1 1 1 1 1 1 1 2 2 2 2
Run Code Online (Sandbox Code Playgroud)

但是,有两个问题:数字太小; 而且,我们缺少第一个元素(第一个类中应该有四个元素).

第一个问题简单地解决了:1+cumsum(nonpos).第二个只需要1在向量的前面添加一个,因为第一个元素总是在类中1:

 > classes <- c(1, 1 + cumsum(nonpos))
 > classes
  [1] 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3
Run Code Online (Sandbox Code Playgroud)

现在,我们可以将它附加到我们的数据框上cbind(通过使用class=语法,我们可以给列class标题):

 > data_w_classes <- cbind(data, class=classes)
Run Code Online (Sandbox Code Playgroud)

data_w_classes现在包含的结果.

最后结果

我们可以将这些行压缩在一起并将其全部包装成一个函数,以便于使用:

classify <- function(data) {
   cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
Run Code Online (Sandbox Code Playgroud)

或者,因为它class是一个因素是有意义的:

classify <- function(data) {
   cbind(data, class=factor(c(1, 1 + cumsum(diff(data$h_no) <= 0))))
}
Run Code Online (Sandbox Code Playgroud)

您使用以下任一功能:

> classified <- classify(data) # doesn't overwrite data
> data <- classify(data) # data now has the "class" column
Run Code Online (Sandbox Code Playgroud)

(这种解决这个问题的方法很好,因为它避免了显式迭代,这通常建议用于R,并且避免生成大量的中间向量和列表等.而且它有点简洁如何在一行上写:))