Разделите только один столбец вложенных данных. Сделаны целочисленным значением

StackOverflow https://stackoverflow.com//questions/24010366

  •  21-12-2019
  •  | 
  •  

Вопрос

Я хочу разделить третий столбец DataFrame на 5. Эти данные данные вложены и выглядят так:

[[44]]
    Ethnicity      Variant  Sum
 1:       ASW     ACCEPTOR    1
 2:       ASW          CDS   68
 3:       ASW   CGA_CNVWIN 1000
 4:       ASW     CGA_MIRB    0
 5:       ASW       DELETE    0
 6:       ASW      DISRUPT    0
 7:       ASW        DONOR    0
 8:       ASW   FRAMESHIFT    0
 9:       ASW       INSERT    1
10:       ASW       INTRON   54
.

Я использовал три команды, каждый из которых успешно, но имеет эффекты вне целей.

lapply(ASWldtSUM,function(x)(x/5))
.

Возвращает

[[44]]
    Ethnicity Variant   Sum
 1:        NA      NA   0.2
 2:        NA      NA  13.6
 3:        NA      NA 200.0
 4:        NA      NA   0.0
 5:        NA      NA   0.0
.

, который имеет несчастный эффект разделения всех строк на 5, что приводит к проблемам, когда класс не является целогом, как в столбце $ SUM.

lapply(ASWldtSUM,function(x[,3])(x/5))
.

имеет эффект возврата только одного вектора, который бы хорошо работал, если бы не было вложенным массивом данных DataFrames, а оператор

ASWdtSUM$NEWCOL<-lapply(ASWldtSUM,function(x[,3])(x/5))
.

не может быть просто написано, потому что он вложен.

Использование Rapply, как в следующем операторе:

rapply(ASWldtSUM,function(x) if (is.integer(x)) {(x/5)})
.

приводит к расстройству результатов.

Итак, есть ли простой способ либо добавить 4-й столбец к каждому вложенному dataframe или заменить третий столбец каждой DF (сумму) с этим значением, разделенным на 5?

Это было полезно?

Решение

Это очень просто, если ASWldtSUM - это имя списка, содержащего кадры данных, то вы можете сделать:

lapply(ASWldtSUM,FUN=function(x) { x[,3]=x[,3]/5; return(x) })
.

в основном вы заменяете (целый) третий столбец с разделением (цельного) третьего колония на пять.

На практике:

> ASWldtSUM1=data.frame(Ethnicity=rep('ASW',10),Variant=c("ACCEPTOR","CDS","CGA_CNVWIN","CGA_MIRB","DELETE","DISRUPT","DONOR","FRAMESHIFT","INSERT","INTRON"), Sum=c(1,68,1000,0,0,0,0,0,1,54))
> #created a first data.frame (equal to your example)
> ASWldtSUM2=data.frame(Ethnicity=rep('ASW',10),Variant=c("ACCEPTOR","CDS","CGA_CNVWIN","CGA_MIRB","DELETE","DISRUPT","DONOR","FRAMESHIFT","INSERT","INTRON"), Sum=c(1,2,3,4,5,6,7,8,9,10))
> #created a second data.frame (with different values for the third column)
> ASWldtSUM=list(ASWldtSUM1,ASWldtSUM2)
> #created a list of data frames
> lapply(ASWldtSUM,FUN=function(x) { x[,3]=x[,3]/5; return(x) })
> #apply the function to divide third column to each nested data.frame
[[1]]
   Ethnicity    Variant   Sum
1        ASW   ACCEPTOR   0.2
2        ASW        CDS  13.6
3        ASW CGA_CNVWIN 200.0
4        ASW   CGA_MIRB   0.0
5        ASW     DELETE   0.0
6        ASW    DISRUPT   0.0
7        ASW      DONOR   0.0
8        ASW FRAMESHIFT   0.0
9        ASW     INSERT   0.2
10       ASW     INTRON  10.8

[[2]]
   Ethnicity    Variant Sum
1        ASW   ACCEPTOR 0.2
2        ASW        CDS 0.4
3        ASW CGA_CNVWIN 0.6
4        ASW   CGA_MIRB 0.8
5        ASW     DELETE 1.0
6        ASW    DISRUPT 1.2
7        ASW      DONOR 1.4
8        ASW FRAMESHIFT 1.6
9        ASW     INSERT 1.8
10       ASW     INTRON 2.0
> #desired result
.

Другие советы

Есть много способов сделать это.Вот один:

Создайте некоторые примеры данных:

dat <- lapply(1:3, function(x)data.frame(a=sample(letters, 4), b=sample(LETTERS, 4), z=rnorm(4)))

dat
[[1]]
  a b          z
1 r M  0.3054329
2 v I -0.8051859
3 t Q -1.6082701
4 u D -0.2315290

[[2]]
  a b          z
1 j W -0.4692469
2 f S  0.3112689
3 a D  0.4208704
4 w Z  0.6903139

[[3]]
....
. Далее, используйте небольшую анонимную функцию внутри lapply().Для лучшей иллюстрации я умножу на 100, а не делишь на 5:

lapply(dat, function(x){x[3] <- x[3]*100; x})

[[1]]
  a b          z
1 r M   30.54329
2 v I  -80.51859
3 t Q -160.82701
4 u D  -23.15290

[[2]]
  a b         z
1 j W -46.92469
2 f S  31.12689
3 a D  42.08704
4 w Z  69.03139

[[3]]
....
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top