it-swarm.asia

إسقاط أعمدة إطار البيانات بالاسم

لدي عدد من الأعمدة التي أود إزالتها من إطار البيانات. أعلم أنه يمكننا حذفها بشكل فردي باستخدام شيء مثل:

df$x <- NULL

لكنني كنت آمل أن أفعل ذلك بأوامر أقل.

أعلم أيضًا أنه يمكنني إسقاط أعمدة باستخدام فهرسة عدد صحيح مثل هذا:

df <- df[ -c(1, 3:6, 12) ]

لكنني قلق من أن الوضع النسبي لمتغيراتي قد يتغير.

نظرًا لمدى قوة R ، فكنت أحسب أن هناك طريقة أفضل من إسقاط كل عمود واحد تلو الآخر.

759
Btibert3

يمكنك استخدام قائمة بسيطة من الأسماء:

DF <- data.frame(
  x=1:10,
  y=10:1,
  z=rep(5,10),
  a=11:20
)
drops <- c("x","z")
DF[ , !(names(DF) %in% drops)]

أو بدلاً من ذلك ، يمكنك إنشاء قائمة بأسماء هؤلاء الأشخاص للإبقاء عليهم والرجوع إليهم بالاسم:

keeps <- c("y", "a")
DF[keeps]

تحرير: بالنسبة لأولئك الذين لم يتعرفوا بعد على الوسيطة drop الخاصة بوظيفة الفهرسة ، إذا كنت تريد الاحتفاظ بعمود واحد كإطار بيانات ، فأنت تقوم بما يلي:

keeps <- "y"
DF[ , keeps, drop = FALSE]

drop=TRUE (أو عدم ذكرها) ستسقط أبعادًا غير ضرورية ، وبالتالي تُرجع متجهًا مع قيم العمود y.

811
Joris Meys

هناك أيضًا أمر subset ، مفيد إذا كنت تعرف الأعمدة التي تريدها:

df <- data.frame(a = 1:10, b = 2:11, c = 3:12)
df <- subset(df, select = c(a, c))

تم التحديث بعد تعليق بواسطةhadley: إلى إسقاط أعمدة ، يمكنك القيام بما يلي:

df <- subset(df, select = -c(a, c))
395
Prasad Chalasani
within(df, rm(x))

من الأسهل ، أو لمتغيرات متعددة:

within(df, rm(x, y))

أو إذا كنت تتعامل مع data.tables (لكل كيف يمكنك حذف عمود حسب الاسم في data.table؟ ):

dt[, x := NULL]   # Deletes column x by reference instantly.

dt[, !"x"]   # Selects all but x into a new data.table.

أو لمتغيرات متعددة

dt[, c("x","y") := NULL]

dt[, !c("x", "y")]
150
Max Ghenis

يمكنك استخدام %in% كما يلي:

df[, !(colnames(df) %in% c("x","bar","foo"))]
101
Joshua Ulrich

قائمة (فارغة) تعمل أيضا:

dat <- mtcars
colnames(dat)
# [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
# [11] "carb"
dat[,c("mpg","cyl","wt")] <- list(NULL)
colnames(dat)
# [1] "disp" "hp"   "drat" "qsec" "vs"   "am"   "gear" "carb"
44
Vincent

هناك إستراتيجية محتملة أكثر استنادًا إلى حقيقة أن grep () سيعود متجهًا رقميًا. إذا كان لديك قائمة طويلة من المتغيرات كما أفعل في أحد مجموعات البيانات الخاصة بي ، فإن بعض المتغيرات التي تنتهي بـ ".A" وغيرها من المتغيرات تنتهي بـ ".B" وتريد فقط المتغيرات التي تنتهي بـ ".A" (على طول مع كل المتغيرات التي لا تتطابق مع أي من النسختين ، قم بهذا:

dfrm2 <- dfrm[ , -grep("\\.B$", names(dfrm)) ]

بالنسبة للحالة الحالية ، باستخدام مثال Joris Meys ، فقد لا يكون مضغوطًا ، لكنه سيكون:

DF <- DF[, -grep( paste("^",drops,"$", sep="", collapse="|"), names(DF) )]
37
42-

إذا كنت تريد إزالة الأعمدة حسب المرجع وتجنب النسخ الداخلي المرتبط بـ data.frames ، فيمكنك استخدام الحزمة data.table والوظيفة :=

يمكنك تمرير أسماء متجهات الأحرف إلى الجانب الأيسر من مشغل := ، و NULL كـ RHS.

library(data.table)

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)
# or more simply  DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10) #

DT[, c('a','b') := NULL]

إذا كنت ترغب في تحديد الأسماء كأحد خطوط الاتجاه خارج المكالمة إلى [ ، فقم بلف اسم الكائن في () أو {} لإجبار LHS على التقييم في نطاق الاستدعاء وليس كاسم ضمن نطاق DT.

del <- c('a','b')
DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, (del) := NULL]
DT <-  <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, {del} := NULL]
# force or `c` would also work.   

يمكنك أيضًا استخدام set ، الذي يتجنب الحمل من [.data.table ، ويعمل أيضًا مع data.frames!

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)

# drop `a` from df (no copying involved)

set(df, j = 'a', value = NULL)
# drop `b` from DT (no copying involved)
set(DT, j = 'b', value = NULL)
37
mnel

إجابة dplyr أخرى. إذا كانت المتغيرات الخاصة بك تحتوي على بنية تسمية شائعة ، فيمكنك تجربة starts_with(). فمثلا

library(dplyr)
df <- data.frame(var1 = rnorm(5), var2 = rnorm(5), var3 = rnorm (5), 
                 var4 = rnorm(5), char1 = rnorm(5), char2 = rnorm(5))
df
#        var2      char1        var4       var3       char2       var1
#1 -0.4629512 -0.3595079 -0.04763169  0.6398194  0.70996579 0.75879754
#2  0.5489027  0.1572841 -1.65313658 -1.3228020 -1.42785427 0.31168919
#3 -0.1707694 -0.9036500  0.47583030 -0.6636173  0.02116066 0.03983268
df1 <- df %>% select(-starts_with("char"))
df1
#        var2        var4       var3       var1
#1 -0.4629512 -0.04763169  0.6398194 0.75879754
#2  0.5489027 -1.65313658 -1.3228020 0.31168919
#3 -0.1707694  0.47583030 -0.6636173 0.03983268

إذا كنت تريد إسقاط سلسلة من المتغيرات في إطار البيانات ، يمكنك استخدام :. على سبيل المثال ، إذا أردت إسقاط var2 و var3 و all المتغيرات بينهما ، فستترك فقط مع var1:

df2 <- df1 %>% select(-c(var2:var3) )  
df2
#        var1
#1 0.75879754
#2 0.31168919
#3 0.03983268
22
Pat W.

بدافع الاهتمام ، يؤدي هذا إلى تمييز أحد أوجه التضارب في بناء جملة R العديدة الغريبة. على سبيل المثال إعطاء إطار بيانات عمودين:

df <- data.frame(x=1, y=2)

هذا يعطي إطار البيانات

subset(df, select=-y)

ولكن هذا يعطي ناقل

df[,-2]

تم توضيح كل ذلك في ?[ ولكنه ليس سلوكًا متوقعًا تمامًا. حسنا على الأقل ليس لي ...

20
jkeirstead
DF <- data.frame(
  x=1:10,
  y=10:1,
  z=rep(5,10),
  a=11:20
)
DF

انتاج:

    x  y z  a
1   1 10 5 11
2   2  9 5 12
3   3  8 5 13
4   4  7 5 14
5   5  6 5 15
6   6  5 5 16
7   7  4 5 17
8   8  3 5 18
9   9  2 5 19
10 10  1 5 20

DF[c("a","x")] <- list(NULL)

انتاج:

        y z
    1  10 5
    2   9 5
    3   8 5
    4   7 5
    5   6 5
    6   5 5
    7   4 5
    8   3 5    
    9   2 5
    10  1 5
19
Kun Ren

امكانية اخرى:

df <- df[, setdiff(names(df), c("a", "c"))]

أو

df <- df[, grep('^(a|c)$', names(df), invert=TRUE)]
19
scentoni

فيما يلي طريقة dplyr للتعرف عليها:

#df[ -c(1,3:6, 12) ]  # original
df.cut <- df %>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6)  # with dplyr::select()

يعجبني هذا لأنه سهل القراءة والفهم بدون تعليق توضيحي وقوي لتغيير الأعمدة موضعه داخل إطار البيانات. كما يتبع المصطلح المتجه باستخدام - لإزالة العناصر.

18
c.gutierrez

حل Dplyr

أشك في أن هذا سيحصل على الكثير من الاهتمام هنا ، ولكن إذا كان لديك قائمة بالأعمدة التي تريد إزالتها ، وتريد القيام بذلك في سلسلة dplyr ، أستخدم one_of() في جملة select:

هنا مثال بسيط وقابل للتكرار:

undesired <- c('mpg', 'cyl', 'hp')

mtcars <- mtcars %>%
  select(-one_of(undesired))

يمكن العثور على الوثائق عن طريق تشغيل ?one_of أو هنا:

http://genomicsclass.github.io/book/pages/dplyr_tutorial.html

16
User632716

ما زلت أفكر في أنه يجب أن يكون هناك تعبير أفضل ، ولكن بالنسبة لطرح الأعمدة بالاسم ، فإنني أميل إلى القيام بما يلي:

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)

# return everything except a and c
df <- df[,-match(c("a","c"),names(df))]
df
12
JD Long

هناك وظيفة تسمى dropNamed() في حزمة BBmisc الخاصة بـ Bernd Bischl والتي تقوم بذلك بالضبط.

BBmisc::dropNamed(df, "x")

الميزة هي أنه يتجنب تكرار وسيطة إطار البيانات ، وبالتالي فهو مناسب للأنابيب في magrittr (تمامًا مثل نهج dplyr):

df %>% BBmisc::dropNamed("x")
11
krlmlr

حل آخر إذا كنت لا تريد استخدام @ hadley أعلاه: إذا كان "COLUMN_NAME" هو اسم العمود الذي تريد إسقاطه:

df[,-which(names(df) == "COLUMN_NAME")]
7
Nick Keramaris

خارج select(-one_of(drop_col_names)) الموضحة في الإجابات السابقة ، هناك خياران dplyr آخران لإسقاط الأعمدة باستخدام select() والتي لا تتضمن تحديد جميع أسماء الأعمدة المحددة (باستخدام بيانات نموذج نجوم النجوم dplyr لبعض أنواع أسماء الأعمدة):

library(dplyr)
starwars %>% 
  select(-(name:mass)) %>%        # the range of columns from 'name' to 'mass'
  select(-contains('color')) %>%  # any column name that contains 'color'
  select(-starts_with('bi')) %>%  # any column name that starts with 'bi'
  select(-ends_with('er')) %>%    # any column name that ends with 'er'
  select(-matches('^f.+s$')) %>%  # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%     # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 
5
sbha

أدخل إطار البيانات وسلسلة من أسماء مفصولة بفواصل لإزالة:

remove_features <- function(df, features) {
  rem_vec <- unlist(strsplit(features, ', '))
  res <- df[,!(names(df) %in% rem_vec)]
  return(res)
}

الاستخدام :

remove_features(iris, "Sepal.Length, Petal.Width")

 enter image description here

3
Cybernetic

ابحث عن فهرس الأعمدة التي تريد إسقاطها باستخدام which. أعط هذه الفهارس علامة سلبية (*-1). ثم مجموعة فرعية على تلك القيم ، والتي سوف إزالتها من قاعدة البيانات. هذا مثال.

DF <- data.frame(one=c('a','b'), two=c('c', 'd'), three=c('e', 'f'), four=c('g', 'h'))
DF
#  one two three four
#1   a   d     f    i
#2   b   e     g    j

DF[which(names(DF) %in% c('two','three')) *-1]
#  one four
#1   a    g
#2   b    h
1
milan